Add further progress
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
lock (liveFactory.SyncRoot)
|
||||
{
|
||||
liveFactory.Reset();
|
||||
liveFactory.Refresh(); // TODO: Reset to Reset
|
||||
|
||||
action();
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
<Content Remove="Umbraco\PartialViewMacros\Templates\EditProfile.cshtml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Remove="App_Data\**" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user