Add further progress

This commit is contained in:
Nikolaj
2020-09-02 14:44:01 +02:00
parent 064acda304
commit 1eb7e9c1eb
14 changed files with 117 additions and 93 deletions

View File

@@ -32,7 +32,7 @@ namespace Umbraco.Configuration.Legacy
{
// giant kill switch, default: false
// must be explicitely set to true for anything else to happen
Enable = ConfigurationManager.AppSettings[Prefix + "Enable"] == "true";
Enable = true;
// ensure defaults are initialized for tests
ModelsNamespace = Constants.ModelsBuilder.DefaultModelsNamespace;

View File

@@ -29,7 +29,7 @@ namespace Umbraco.Configuration.Models
/// <para>If this is false then absolutely nothing happens.</para>
/// <para>Default value is <c>false</c> which means that unless we have this setting, nothing happens.</para>
/// </remarks>
public bool Enable => _configuration.GetValue(Prefix+"Enable", false);
public bool Enable => _configuration.GetValue(Prefix+"Enable", true);
/// <summary>
/// Gets the models mode.

View File

@@ -19,7 +19,7 @@ namespace Umbraco.Core.Composing
"Umbraco.Core",
"Umbraco.Infrastructure",
"Umbraco.PublishedCache.NuCache",
// "Umbraco.ModelsBuilder.Embedded", TODO reintroduce when ModelsBuilder is migrated
"Umbraco.ModelsBuilder.Embedded",
"Umbraco.Examine.Lucene",
"Umbraco.Web.Common",
"Umbraco.Web.BackOffice",

View File

@@ -1,5 +1,6 @@
using System.Configuration;
using System.IO;
using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
namespace Umbraco.Core.Configuration
@@ -8,13 +9,13 @@ namespace Umbraco.Core.Configuration
{
private static string _modelsDirectoryAbsolute = null;
public static string ModelsDirectoryAbsolute(this IModelsBuilderConfig modelsBuilderConfig, IIOHelper ioHelper)
public static string ModelsDirectoryAbsolute(this IModelsBuilderConfig modelsBuilderConfig, IHostingEnvironment hostingEnvironment)
{
if (_modelsDirectoryAbsolute is null)
{
var modelsDirectory = modelsBuilderConfig.ModelsDirectory;
var root = ioHelper.MapPath("~/");
var root = hostingEnvironment.MapPathContentRoot("~/");
_modelsDirectoryAbsolute = GetModelsDirectory(root, modelsDirectory,
modelsBuilderConfig.AcceptUnsafeModelsDirectory);

View File

@@ -64,7 +64,7 @@ namespace Umbraco.Core
{
lock (liveFactory.SyncRoot)
{
liveFactory.Reset();
liveFactory.Refresh(); // TODO: Reset to Reset
action();
}

View File

@@ -26,14 +26,11 @@ namespace Umbraco.ModelsBuilder.Embedded.Building
protected readonly IList<string> TypesUsing = new List<string>
{
"System",
"System.Collections.Generic",
"System.Linq.Expressions",
"System.Web",
"Umbraco.Core.Models",
"Umbraco.Core.Models.PublishedContent",
"Umbraco.Web",
"Umbraco.Web.PublishedCache",
"Umbraco.ModelsBuilder.Embedded"
"Umbraco.ModelsBuilder.Embedded",
"Umbraco.Core"
};
/// <summary>

View File

@@ -1,7 +1,7 @@
using System.IO;
using System.Text;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Hosting;
namespace Umbraco.ModelsBuilder.Embedded.Building
{
@@ -10,19 +10,19 @@ namespace Umbraco.ModelsBuilder.Embedded.Building
private readonly UmbracoServices _umbracoService;
private readonly IModelsBuilderConfig _config;
private readonly OutOfDateModelsStatus _outOfDateModels;
private readonly IIOHelper _ioHelper;
private readonly IHostingEnvironment _hostingEnvironment;
public ModelsGenerator(UmbracoServices umbracoService, IModelsBuilderConfig config, OutOfDateModelsStatus outOfDateModels, IIOHelper ioHelper)
public ModelsGenerator(UmbracoServices umbracoService, IModelsBuilderConfig config, OutOfDateModelsStatus outOfDateModels, IHostingEnvironment hostingEnvironment)
{
_umbracoService = umbracoService;
_config = config;
_outOfDateModels = outOfDateModels;
_ioHelper = ioHelper;
_hostingEnvironment = hostingEnvironment;
}
internal void GenerateModels()
{
var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper);
var modelsDirectory = _config.ModelsDirectoryAbsolute(_hostingEnvironment);
if (!Directory.Exists(modelsDirectory))
Directory.CreateDirectory(modelsDirectory);

View File

@@ -191,9 +191,10 @@ namespace Umbraco.ModelsBuilder.Embedded.Building
type.ClrName);
sb.Append("\t\t\t=> PublishedModelUtility.GetModelPropertyType(GetModelContentType(publishedSnapshotAccessor), selector);\n");
sb.Append("#pragma warning restore 0109\n\n");
sb.Append("private IPublishedValueFallback _publishedValueFallback;");
// write the ctor
sb.AppendFormat("\t\t// ctor\n\t\tpublic {0}(IPublished{1} content)\n\t\t\t: base(content)\n\t\t{{ }}\n\n",
sb.AppendFormat("\t\t// ctor\n\t\tpublic {0}(IPublished{1} content, IPublishedValueFallback publishedValueFallback)\n\t\t\t: base(content)\n\t\t{{\n _publishedValueFallback = publishedValueFallback; \n}}\n\n",
type.ClrName, type.IsElement ? "Element" : "Content");
// write the properties
@@ -324,7 +325,7 @@ namespace Umbraco.ModelsBuilder.Embedded.Building
WriteClrType(sb, property.ClrTypeName);
sb.Append(">");
}
sb.AppendFormat("(\"{0}\");\n",
sb.AppendFormat("(_publishedValueFallback, \"{0}\");\n",
property.Alias);
}

View File

@@ -2,6 +2,7 @@
using System.IO;
using System.Text;
using Umbraco.Core.Configuration;
using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
namespace Umbraco.ModelsBuilder.Embedded
@@ -9,12 +10,12 @@ namespace Umbraco.ModelsBuilder.Embedded
public sealed class ModelsGenerationError
{
private readonly IModelsBuilderConfig _config;
private readonly IIOHelper _ioHelper;
private readonly IHostingEnvironment _hostingEnvironment;
public ModelsGenerationError(IModelsBuilderConfig config, IIOHelper ioHelper)
public ModelsGenerationError(IModelsBuilderConfig config, IHostingEnvironment hostingEnvironment)
{
_config = config;
_ioHelper = ioHelper;
_hostingEnvironment = hostingEnvironment;
}
public void Clear()
@@ -59,7 +60,7 @@ namespace Umbraco.ModelsBuilder.Embedded
private string GetErrFile()
{
var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper);
var modelsDirectory = _config.ModelsDirectoryAbsolute(_hostingEnvironment);
if (!Directory.Exists(modelsDirectory))
return null;

View File

@@ -1,5 +1,6 @@
using System.IO;
using Umbraco.Core.Configuration;
using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
using Umbraco.Web.Cache;
@@ -8,12 +9,12 @@ namespace Umbraco.ModelsBuilder.Embedded
public sealed class OutOfDateModelsStatus
{
private readonly IModelsBuilderConfig _config;
private readonly IIOHelper _ioHelper;
private readonly IHostingEnvironment _hostingEnvironment;
public OutOfDateModelsStatus(IModelsBuilderConfig config, IIOHelper ioHelper)
public OutOfDateModelsStatus(IModelsBuilderConfig config, IHostingEnvironment hostingEnvironment)
{
_config = config;
_ioHelper = ioHelper;
_hostingEnvironment = hostingEnvironment;
}
internal void Install()
@@ -28,7 +29,7 @@ namespace Umbraco.ModelsBuilder.Embedded
private string GetFlagPath()
{
var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper);
var modelsDirectory = _config.ModelsDirectoryAbsolute(_hostingEnvironment);
if (!Directory.Exists(modelsDirectory))
Directory.CreateDirectory(modelsDirectory);
return Path.Combine(modelsDirectory, "ood.flag");

View File

@@ -9,8 +9,6 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
using System.Web.Compilation;
using System.Web.WebPages.Razor;
using Umbraco.Core.Configuration;
using Umbraco.Core;
using Umbraco.Core.Hosting;
@@ -19,6 +17,7 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.ModelsBuilder.Embedded.Building;
using File = System.IO.File;
using Umbraco.Core.Composing;
namespace Umbraco.ModelsBuilder.Embedded
{
@@ -33,18 +32,21 @@ namespace Umbraco.ModelsBuilder.Embedded
private readonly FileSystemWatcher _watcher;
private int _ver, _skipver;
private readonly int _debugLevel;
private BuildManager _theBuildManager;
private RoslynCompiler _roslynCompiler;
private readonly Lazy<UmbracoServices> _umbracoServices; // fixme: this is because of circular refs :(
private UmbracoServices UmbracoServices => _umbracoServices.Value;
private static readonly Regex AssemblyVersionRegex = new Regex("AssemblyVersion\\(\"[0-9]+.[0-9]+.[0-9]+.[0-9]+\"\\)", RegexOptions.Compiled);
private const string ProjVirt = "~/App_Data/Models/all.generated.cs";
private const string CodeGen = "~/App_Data/Models/";
private static readonly string[] OurFiles = { "models.hash", "models.generated.cs", "all.generated.cs", "all.dll.path", "models.err" };
private readonly IModelsBuilderConfig _config;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IApplicationShutdownRegistry _hostingLifetime;
private readonly IIOHelper _ioHelper;
private readonly ModelsGenerationError _errors;
private readonly ITypeFinder _typeFinder;
private readonly IPublishedValueFallback _publishedValueFallback;
public PureLiveModelFactory(
Lazy<UmbracoServices> umbracoServices,
@@ -52,22 +54,25 @@ namespace Umbraco.ModelsBuilder.Embedded
IModelsBuilderConfig config,
IHostingEnvironment hostingEnvironment,
IApplicationShutdownRegistry hostingLifetime,
IIOHelper ioHelper)
ITypeFinder typeFinder,
IPublishedValueFallback publishedValueFallback)
{
_umbracoServices = umbracoServices;
_logger = logger;
_config = config;
_hostingEnvironment = hostingEnvironment;
_hostingLifetime = hostingLifetime;
_ioHelper = ioHelper;
_errors = new ModelsGenerationError(config, ioHelper);
_typeFinder = typeFinder;
_publishedValueFallback = publishedValueFallback;
_errors = new ModelsGenerationError(config, _hostingEnvironment);
_ver = 1; // zero is for when we had no version
_skipver = -1; // nothing to skip
RazorBuildProvider.CodeGenerationStarted += RazorBuildProvider_CodeGenerationStarted;
// RazorBuildProvider.CodeGenerationStarted += RazorBuildProvider_CodeGenerationStarted;
if (!hostingEnvironment.IsHosted) return;
var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper);
var modelsDirectory = _config.ModelsDirectoryAbsolute(_hostingEnvironment);
if (!Directory.Exists(modelsDirectory))
Directory.CreateDirectory(modelsDirectory);
@@ -113,7 +118,7 @@ namespace Umbraco.ModelsBuilder.Embedded
infos.TryGetValue(contentTypeAlias, out var info);
// create model
return info == null ? element : info.Ctor(element);
return info == null ? element : info.Ctor(element, _publishedValueFallback);
}
// this runs only once the factory is ready
@@ -200,13 +205,14 @@ namespace Umbraco.ModelsBuilder.Embedded
if (_debugLevel > 0)
_logger.Debug<PureLiveModelFactory>("RazorBuildProvider.CodeGenerationStarted");
if (!(sender is RazorBuildProvider provider)) return;
// TODO: How to handle this?
// if (!(sender is RazorBuildProvider provider)) return;
// add the assembly, and add a dependency to a text file that will change on each
// compilation as in some environments (could not figure which/why) the BuildManager
// would not re-compile the views when the models assembly is rebuilt.
provider.AssemblyBuilder.AddAssemblyReference(_modelsAssembly);
provider.AddVirtualPathDependency(ProjVirt);
//provider.AssemblyBuilder.AddAssemblyReference(_modelsAssembly);
//provider.AddVirtualPathDependency(ProjVirt);
}
finally
{
@@ -227,7 +233,7 @@ namespace Umbraco.ModelsBuilder.Embedded
_hasModels = false;
_pendingRebuild = true;
var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper);
var modelsDirectory = _config.ModelsDirectoryAbsolute(_hostingEnvironment);
if (!Directory.Exists(modelsDirectory))
Directory.CreateDirectory(modelsDirectory);
@@ -248,16 +254,13 @@ namespace Umbraco.ModelsBuilder.Embedded
}
// gets "the" build manager
private BuildManager TheBuildManager
private RoslynCompiler RoslynCompiler
{
get
{
if (_theBuildManager != null) return _theBuildManager;
var prop = typeof(BuildManager).GetProperty("TheBuildManager", BindingFlags.NonPublic | BindingFlags.Static);
if (prop == null)
throw new InvalidOperationException("Could not get BuildManager.TheBuildManager property.");
_theBuildManager = (BuildManager)prop.GetValue(null);
return _theBuildManager;
if (_roslynCompiler != null) return _roslynCompiler;
_roslynCompiler = new RoslynCompiler(System.Runtime.Loader.AssemblyLoadContext.All.SelectMany(x => x.Assemblies));
return _roslynCompiler;
}
}
@@ -285,7 +288,7 @@ namespace Umbraco.ModelsBuilder.Embedded
{
// always take the BuildManager lock *before* taking the _locker lock
// to avoid possible deadlock situations (see notes above)
Monitor.Enter(TheBuildManager, ref buildManagerLocked);
Monitor.Enter(RoslynCompiler, ref buildManagerLocked);
_locker.EnterUpgradeableReadLock();
@@ -343,13 +346,13 @@ namespace Umbraco.ModelsBuilder.Embedded
if (_locker.IsUpgradeableReadLockHeld)
_locker.ExitUpgradeableReadLock();
if (buildManagerLocked)
Monitor.Exit(TheBuildManager);
Monitor.Exit(RoslynCompiler);
}
}
private Assembly GetModelsAssembly(bool forceRebuild)
{
var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper);
var modelsDirectory = _config.ModelsDirectoryAbsolute(_hostingEnvironment);
if (!Directory.Exists(modelsDirectory))
Directory.CreateDirectory(modelsDirectory);
@@ -402,7 +405,7 @@ namespace Umbraco.ModelsBuilder.Embedded
if (File.Exists(dllPathFile))
{
var dllPath = File.ReadAllText(dllPathFile);
var codegen = HttpRuntime.CodegenDir;
var codegen = CodeGen;
_logger.Debug<PureLiveModelFactory>($"Cached models dll at {dllPath}.");
@@ -452,7 +455,7 @@ namespace Umbraco.ModelsBuilder.Embedded
_ver++;
try
{
assembly = BuildManager.GetCompiledAssembly(ProjVirt);
assembly = RoslynCompiler.GetCompiledAssembly(_hostingEnvironment.MapPathContentRoot(ProjVirt), Path.Combine(_hostingEnvironment.ApplicationPhysicalPath, "App_Data", $"generated.cs.{currentHash}.dll"));
File.WriteAllText(dllPathFile, assembly.Location);
}
catch
@@ -490,7 +493,7 @@ namespace Umbraco.ModelsBuilder.Embedded
// compile and register
try
{
assembly = BuildManager.GetCompiledAssembly(ProjVirt);
assembly = RoslynCompiler.GetCompiledAssembly(_hostingEnvironment.MapPathContentRoot(ProjVirt), Path.Combine(_hostingEnvironment.ApplicationPhysicalPath, "App_Data", $"generated.cs.{currentHash}.dll"));
File.WriteAllText(dllPathFile, assembly.Location);
File.WriteAllText(modelsHashFile, currentHash);
}
@@ -523,7 +526,7 @@ namespace Umbraco.ModelsBuilder.Embedded
private static Infos RegisterModels(IEnumerable<Type> types)
{
var ctorArgTypes = new[] { typeof(IPublishedElement) };
var ctorArgTypes = new[] { typeof(IPublishedElement), typeof(IPublishedValueFallback) };
var modelInfos = new Dictionary<string, ModelInfo>(StringComparer.InvariantCultureIgnoreCase);
var map = new Dictionary<string, Type>();
@@ -535,7 +538,7 @@ namespace Umbraco.ModelsBuilder.Embedded
foreach (var ctor in type.GetConstructors())
{
var parms = ctor.GetParameters();
if (parms.Length == 1 && typeof(IPublishedElement).IsAssignableFrom(parms[0].ParameterType))
if (parms.Length == 2 && typeof(IPublishedElement).IsAssignableFrom(parms[0].ParameterType) && typeof(IPublishedValueFallback).IsAssignableFrom(parms[1].ParameterType))
{
if (constructor != null)
throw new InvalidOperationException($"Type {type.FullName} has more than one public constructor with one argument of type, or implementing, IPropertySet.");
@@ -562,7 +565,7 @@ namespace Umbraco.ModelsBuilder.Embedded
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Newobj, constructor);
gen.Emit(OpCodes.Ret);
var func = (Func<IPublishedElement, IPublishedElement>)meth.CreateDelegate(typeof(Func<IPublishedElement, IPublishedElement>));
var func = (Func<IPublishedElement, IPublishedValueFallback, IPublishedElement>)meth.CreateDelegate(typeof(Func<IPublishedElement, IPublishedValueFallback, IPublishedElement>));
modelInfos[typeName] = new ModelInfo { ParameterType = parameterType, Ctor = func, ModelType = type };
map[typeName] = type;
@@ -573,7 +576,7 @@ namespace Umbraco.ModelsBuilder.Embedded
private string GenerateModelsCode(IList<TypeModel> typeModels)
{
var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper);
var modelsDirectory = _config.ModelsDirectoryAbsolute(_hostingEnvironment);
if (!Directory.Exists(modelsDirectory))
Directory.CreateDirectory(modelsDirectory);
@@ -651,7 +654,7 @@ namespace Umbraco.ModelsBuilder.Embedded
internal class ModelInfo
{
public Type ParameterType { get; set; }
public Func<IPublishedElement, IPublishedElement> Ctor { get; set; }
public Func<IPublishedElement, IPublishedValueFallback, IPublishedElement> Ctor { get; set; }
public Type ModelType { get; set; }
public Func<IList> ListCtor { get; set; }
}

View File

@@ -9,12 +9,12 @@ namespace Umbraco.ModelsBuilder.Embedded
internal static class ReferencedAssemblies
{
private static readonly Lazy<IEnumerable<string>> LazyLocations;
// TODO: Do we even use this anymore?
static ReferencedAssemblies()
{
LazyLocations = new Lazy<IEnumerable<string>>(() => Current.HostingEnvironment.IsHosted // fixme inject!
? GetAllReferencedAssembliesLocationFromBuildManager()
: GetAllReferencedAssembliesFromDomain());
//LazyLocations = new Lazy<IEnumerable<string>>(() => Current.HostingEnvironment.IsHosted // fixme inject!
// ? GetAllReferencedAssembliesLocationFromBuildManager()
// : GetAllReferencedAssembliesFromDomain());
}
/// <summary>
@@ -26,7 +26,7 @@ namespace Umbraco.ModelsBuilder.Embedded
public static Assembly GetNetStandardAssembly(List<Assembly> assemblies)
{
if (assemblies == null)
assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList();
//assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList();
// for some reason, netstandard is also missing from BuildManager.ReferencedAssemblies and yet, is part of
// the references that CSharpCompiler (above) receives - where is it coming from? cannot figure it out
@@ -60,34 +60,34 @@ namespace Umbraco.ModelsBuilder.Embedded
}
// hosted, get referenced assemblies from the BuildManager and filter
private static IEnumerable<string> GetAllReferencedAssembliesLocationFromBuildManager()
{
var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList();
//private static IEnumerable<string> GetAllReferencedAssembliesLocationFromBuildManager()
//{
// //var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList();
assemblies.Add(typeof(ReferencedAssemblies).Assembly); // always include ourselves
// assemblies.Add(typeof(ReferencedAssemblies).Assembly); // always include ourselves
// see https://github.com/aspnet/RoslynCodeDomProvider/blob/master/src/Microsoft.CodeDom.Providers.DotNetCompilerPlatform/CSharpCompiler.cs:
// mentions "Bug 913691: Explicitly add System.Runtime as a reference."
// and explicitly adds System.Runtime to references before invoking csc.exe
// so, doing the same here
try
{
var systemRuntime = Assembly.Load("System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
assemblies.Add(systemRuntime);
}
catch { /* never mind */ }
// // see https://github.com/aspnet/RoslynCodeDomProvider/blob/master/src/Microsoft.CodeDom.Providers.DotNetCompilerPlatform/CSharpCompiler.cs:
// // mentions "Bug 913691: Explicitly add System.Runtime as a reference."
// // and explicitly adds System.Runtime to references before invoking csc.exe
// // so, doing the same here
// try
// {
// var systemRuntime = Assembly.Load("System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
// assemblies.Add(systemRuntime);
// }
// catch { /* never mind */ }
// for some reason, netstandard is also missing from BuildManager.ReferencedAssemblies and yet, is part of
// the references that CSharpCompiler (above) receives - where is it coming from? cannot figure it out
var netStandard = GetNetStandardAssembly(assemblies);
if (netStandard != null) assemblies.Add(netStandard);
// // for some reason, netstandard is also missing from BuildManager.ReferencedAssemblies and yet, is part of
// // the references that CSharpCompiler (above) receives - where is it coming from? cannot figure it out
// var netStandard = GetNetStandardAssembly(assemblies);
// if (netStandard != null) assemblies.Add(netStandard);
return assemblies
.Where(x => !x.IsDynamic && !x.Location.IsNullOrWhiteSpace())
.Select(x => x.Location)
.Distinct()
.ToList();
}
// return assemblies
// .Where(x => !x.IsDynamic && !x.Location.IsNullOrWhiteSpace())
// .Select(x => x.Location)
// .Distinct()
// .ToList();
//}
// non-hosted, do our best
private static IEnumerable<string> GetAllReferencedAssembliesFromDomain()

View File

@@ -5,6 +5,7 @@ using Microsoft.CodeAnalysis.Text;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
@@ -14,21 +15,38 @@ namespace Umbraco.ModelsBuilder.Embedded
{
private OutputKind _outputKind;
private CSharpParseOptions _parseOptions;
private List<MetadataReference> _refs;
public RoslynCompiler()
public RoslynCompiler(IEnumerable<Assembly> referenceAssemblies)
{
_outputKind = OutputKind.DynamicallyLinkedLibrary;
_parseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest); // What languageversion should we default to?
// The references should be the same every time GetCompiledAssembly is called
// Making it kind of a waste to convert the Assembly types into MetadataReference
// every time GetCompiledAssembly is called, so that's why I do it in the ctor
_refs = new List<MetadataReference>();
foreach(var assembly in referenceAssemblies.Where(x => !x.IsDynamic && !string.IsNullOrWhiteSpace(x.Location)))
{
_refs.Add(MetadataReference.CreateFromFile(assembly.Location));
};
// Might have to do this another way, see
// see https://github.com/aspnet/RoslynCodeDomProvider/blob/master/src/Microsoft.CodeDom.Providers.DotNetCompilerPlatform/CSharpCompiler.cs:
// mentions "Bug 913691: Explicitly add System.Runtime as a reference."
// and explicitly adds System.Runtime to references before invoking csc.exe
_refs.Add(MetadataReference.CreateFromFile(typeof(System.Runtime.AssemblyTargetedPatchBandAttribute).Assembly.Location));
_refs.Add(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
_refs.Add(MetadataReference.CreateFromFile(typeof(System.CodeDom.Compiler.GeneratedCodeAttribute).Assembly.Location));
}
public Assembly GetCompiledAssembly(string pathToSourceFile, IEnumerable<MetadataReference> refs)
public Assembly GetCompiledAssembly(string pathToSourceFile, string saveLocation)
{
// TODO: Get proper temp file location/filename
var outputPath = $"generated.cs.{Guid.NewGuid()}.dll";
var sourceCode = File.ReadAllText(pathToSourceFile);
CompileToFile(outputPath, sourceCode, "ModelsGenerated", refs);
return Assembly.LoadFile(outputPath);
CompileToFile(saveLocation, sourceCode, "ModelsGeneratedAssembly", _refs);
return Assembly.LoadFile(saveLocation);
}
@@ -46,7 +64,8 @@ namespace Umbraco.ModelsBuilder.Embedded
// Not entirely certain that assemblyIdentityComparer is nececary?
assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default));
compilation.Emit(outputFile);
var result = compilation.Emit(outputFile);
}
}
}

View File

@@ -98,6 +98,7 @@
<Content Remove="Umbraco\PartialViewMacros\Templates\EditProfile.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Remove="App_Data\**" />
</ItemGroup>