Commits progress so far, then will cleanup a bunch

This commit is contained in:
Shannon
2021-01-19 15:46:25 +11:00
parent 5f9447fc2a
commit f320d41b1d
4 changed files with 285 additions and 197 deletions

View File

@@ -27,6 +27,47 @@ using Umbraco.ModelsBuilder.Embedded.Building;
using Umbraco.ModelsBuilder.Embedded.DependencyInjection;
using Umbraco.Web.WebAssets;
/*
* OVERVIEW:
*
* The CSharpCompiler is responsible for the actual compilation of razor at runtime.
* It creates a CSharpCompilation instance to do the compilation. This is where DLL references
* are applied. However, the way this works is not flexible for dynamic assemblies since the references
* are only discovered and loaded once before the first compilation occurs. This is done here:
* https://github.com/dotnet/aspnetcore/blob/114f0f6d1ef1d777fb93d90c87ac506027c55ea0/src/Mvc/Mvc.Razor.RuntimeCompilation/src/CSharpCompiler.cs#L79
* The CSharpCompiler is internal and cannot be replaced or extended, however it's references come from:
* RazorReferenceManager. Unfortunately this is also internal and cannot be replaced, though it can be extended
* using MvcRazorRuntimeCompilationOptions, except this is the place where references are only loaded once which
* is done with a LazyInitializer. See https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/Mvc.Razor.RuntimeCompilation/src/RazorReferenceManager.cs#L35.
*
* The way that RazorReferenceManager works is by resolving references from the ApplicationPartsManager - either by
* an application part that is specifically an ICompilationReferencesProvider or an AssemblyPart. So to fulfill this
* requirement, we add the MB assembly to the assembly parts manager within the PureLiveModelFactory when the assembly
* is (re)generated. But due to the above restrictions, when re-generating, this will have no effect since the references
* have already been resolved with the LazyInitializer in the RazorReferenceManager.
*
* The services that can be replaced are: IViewCompilerProvider (default is the internal RuntimeViewCompilerProvider) and
* IViewCompiler (default is the internal RuntimeViewCompiler).
*
* There are caches at several levels, all of which are not publicly accessible APIs (apart from RazorViewEngine.ViewLookupCache).
* For this to work, several caches must be cleared:
* - RazorViewEngine.ViewLookupCache
* - RazorReferencesManager._compilationReferences
* - RazorPageActivator._activationInfo (though this one may be optional)
* - RuntimeViewCompiler._cache
*
* What are our options?
*
* a) We can copy a ton of code into our application: CSharpCompiler, RuntimeViewCompilerProvider, RuntimeViewCompiler and
* RazorReferenceManager (probably more depending on the extent of Internal references).
* b) We can use reflection to try to access all of the above resources and try to forcefully clear caches and reset initialization flags.
* c) We hack these replace-able services with our own implementations that wrap the default services. To do this
* requires re-resolving the original services from a pre-built DI container. In effect this re-creates these
* services from scratch which means there is no caches.
*
* ... Option C works, we will use that but need to verify how this affects memory since ideally the old services will be GC'd.
*/
// This is the insanity that allows you to customize the RazorProjectEngineBuilder
[assembly: ProvideRazorExtensionInitializer("ModelsBuilderPureLive", typeof(ModelsBuilderRazorProjectBuilderExtension))]
@@ -60,22 +101,6 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
if (config.ModelsMode == ModelsMode.PureLive)
{
return factory.GetRequiredService<PureLiveModelFactory>();
// the following would add @using statement in every view so user's don't
// have to do it - however, then noone understands where the @using statement
// comes from, and it cannot be avoided / removed --- DISABLED
/*
// no need for @using in views
// note:
// we are NOT using the in-code attribute here, config is required
// because that would require parsing the code... and what if it changes?
// we can AddGlobalImport not sure we can remove one anyways
var modelsNamespace = Configuration.Config.ModelsNamespace;
if (string.IsNullOrWhiteSpace(modelsNamespace))
modelsNamespace = Configuration.Config.DefaultModelsNamespace;
System.Web.WebPages.Razor.WebPageRazorHost.AddGlobalImport(modelsNamespace);
*/
}
else if (config.EnableFactory)
{
@@ -123,28 +148,28 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
builder.Services
};
builder.Services.AddSingleton<RazorProjectEngine>(
s => new RefreshingRazorProjectEngine(defaultRazorProjectEngine, s, s.GetRequiredService<PureLiveModelFactory>()));
//builder.Services.AddSingleton<RazorProjectEngine>(
// s => new RefreshingRazorProjectEngine(defaultRazorProjectEngine, s, s.GetRequiredService<PureLiveModelFactory>()));
builder.Services.AddSingleton<IViewCompilerProvider>(
s => new RefreshingRuntimeViewCompilerProvider(
() =>
{
// re-create the original container so that a brand new IViewCompilerProvider
// is produced, if we don't re-create the container then it will just return the same instance.
ServiceProvider recreatedServices = initialCollection.BuildServiceProvider();
return recreatedServices.GetRequiredService<IViewCompilerProvider>();
}, s.GetRequiredService<PureLiveModelFactory>()));
//builder.Services.AddSingleton<IViewCompilerProvider>(
// s => new RefreshingRuntimeViewCompilerProvider(
// () =>
// {
// // re-create the original container so that a brand new IViewCompilerProvider
// // is produced, if we don't re-create the container then it will just return the same instance.
// ServiceProvider recreatedServices = initialCollection.BuildServiceProvider();
// return recreatedServices.GetRequiredService<IViewCompilerProvider>();
// }, s.GetRequiredService<PureLiveModelFactory>()));
builder.Services.AddSingleton<IRazorPageActivator>(
s => new RefreshingRazorPageActivator(
() =>
{
// re-create the original container so that a brand new IRazorPageActivator
// is produced, if we don't re-create the container then it will just return the same instance.
ServiceProvider recreatedServices = initialCollection.BuildServiceProvider();
return recreatedServices.GetRequiredService<IRazorPageActivator>();
}, s.GetRequiredService<PureLiveModelFactory>()));
//builder.Services.AddSingleton<IRazorPageActivator>(
// s => new RefreshingRazorPageActivator(
// () =>
// {
// // re-create the original container so that a brand new IRazorPageActivator
// // is produced, if we don't re-create the container then it will just return the same instance.
// ServiceProvider recreatedServices = initialCollection.BuildServiceProvider();
// return recreatedServices.GetRequiredService<IRazorPageActivator>();
// }, s.GetRequiredService<PureLiveModelFactory>()));
builder.Services.AddSingleton<IRazorViewEngine>(
s => new RefreshingRazorViewEngine(
@@ -156,6 +181,8 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
return recreatedServices.GetRequiredService<IRazorViewEngine>();
}, s.GetRequiredService<PureLiveModelFactory>()));
//builder.Services.AddSingleton<IRazorViewEngine, RefreshingRazorViewEngine>();
return builder;
}
}
@@ -171,7 +198,22 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
// Now... customize
// TODO: BUT This is called before all of the default options are done, argh! so you can't replace anything here anyways
builder.Phases.Add(new CustomRazorPhase());
// NOTE: This is called before all of the default options that are applied
// in AddRazorRuntimeCompilation, see https://github.com/dotnet/aspnetcore/blob/336e05577cd8bec2000ffcada926189199e4cef0/src/Mvc/Mvc.Razor.RuntimeCompilation/src/DependencyInjection/RazorRuntimeCompilationMvcCoreBuilderExtensions.cs#L88
// are done so you can't replace anything here that is added by the default razor runtime compilation.
}
}
internal class CustomRazorPhase : RazorEnginePhaseBase, IRazorEnginePhase
{
protected override void ExecuteCore(RazorCodeDocument codeDocument)
{
// it's possible to modify the razor generated document with custom phases.
// like possibly setting default import statements, etc..
// there's no documentation on this so you'll need to read the source code to figure
// that one out if we ever wanted it.
}
}
@@ -184,39 +226,61 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
public IServiceProvider ServiceProvider { get; }
}
// The default razor page activator keeps an internal cache of activations, this allows clearning that cache
// TODO: Find out if we really need to clear this cache or not? Or if just clearing the view engine cache is enough?
internal class RefreshingRazorPageActivator : IRazorPageActivator
{
private readonly Func<IRazorPageActivator> _defaultRazorPageActivatorFactory;
private readonly PureLiveModelFactory _pureLiveModelFactory;
private IRazorPageActivator _current;
//// The default razor page activator keeps an internal cache of activations, this allows clearning that cache
//// TODO: Find out if we really need to clear this cache or not? Or if just clearing the view engine cache is enough?
//internal class RefreshingRazorPageActivator : IRazorPageActivator
//{
// private readonly Func<IRazorPageActivator> _defaultRazorPageActivatorFactory;
// private readonly PureLiveModelFactory _pureLiveModelFactory;
// private IRazorPageActivator _current;
public RefreshingRazorPageActivator(
Func<IRazorPageActivator> defaultRazorPageActivatorFactory,
PureLiveModelFactory pureLiveModelFactory)
{
_pureLiveModelFactory = pureLiveModelFactory;
_defaultRazorPageActivatorFactory = defaultRazorPageActivatorFactory;
_current = _defaultRazorPageActivatorFactory();
_pureLiveModelFactory.ModelsChanged += PureLiveModelFactory_ModelsChanged;
}
// public RefreshingRazorPageActivator(
// Func<IRazorPageActivator> defaultRazorPageActivatorFactory,
// PureLiveModelFactory pureLiveModelFactory)
// {
// _pureLiveModelFactory = pureLiveModelFactory;
// _defaultRazorPageActivatorFactory = defaultRazorPageActivatorFactory;
// _current = _defaultRazorPageActivatorFactory();
// _pureLiveModelFactory.ModelsChanged += PureLiveModelFactory_ModelsChanged;
// }
// TODO: Do we need to lock?
private void PureLiveModelFactory_ModelsChanged(object sender, EventArgs e) => _current = _defaultRazorPageActivatorFactory();
// // TODO: Do we need to lock?
// private void PureLiveModelFactory_ModelsChanged(object sender, EventArgs e) => _current = _defaultRazorPageActivatorFactory();
public void Activate(IRazorPage page, ViewContext context) => _current.Activate(page, context);
}
// public void Activate(IRazorPage page, ViewContext context) => _current.Activate(page, context);
//}
// We need to have a refreshing razor view engine - the default keeps an in memory cache of views and it cannot be cleared because
// the cache key instance is internal and would require manually tracking all keys since it cannot be iterated.
// So like other 'Refreshing' intances, we just create a brand new one and let the old one die therefore clearing the cache.
internal class RefreshingRazorViewEngine : IRazorViewEngine
// TODO: It looks like dynamic recompile works just fine with "only" the refreshing razor view engine BUT
// that's also because it creates a new instance of the IRazorPageActivator since when resolving the engine
// again it's of course going to resolve all dependencies as well which is a few:
// https://github.com/dotnet/aspnetcore/blob/e37ddbcdbc445a65c6f51549775d5924423880e4/src/Mvc/Mvc.Razor/src/RazorViewEngine.cs#L51
// which isn't ideal.
// There's no real way to clear the cache since we cannot iterate and have no access to the cache key instance
internal class RefreshingRazorViewEngine : /*RazorViewEngine,*/ IRazorViewEngine
{
private IRazorViewEngine _current;
private readonly PureLiveModelFactory _pureLiveModelFactory;
private readonly Func<IRazorViewEngine> _defaultRazorViewEngineFactory;
//public RefreshingRazorViewEngine(
// PureLiveModelFactory pureLiveModelFactory,
// IRazorPageFactoryProvider pageFactory,
// IRazorPageActivator pageActivator,
// HtmlEncoder htmlEncoder,
// IOptions<RazorViewEngineOptions> optionsAccessor,
// ILoggerFactory loggerFactory,
// DiagnosticListener diagnosticListener)
// : base(pageFactory, pageActivator, htmlEncoder, optionsAccessor, loggerFactory, diagnosticListener)
//{
// _pureLiveModelFactory = pureLiveModelFactory;
// _pureLiveModelFactory.ModelsChanged += PureLiveModelFactory_ModelsChanged;
//}
public RefreshingRazorViewEngine(Func<IRazorViewEngine> defaultRazorViewEngineFactory, PureLiveModelFactory pureLiveModelFactory)
{
_pureLiveModelFactory = pureLiveModelFactory;
@@ -226,7 +290,15 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
}
// TODO: Do we need to lock?
private void PureLiveModelFactory_ModelsChanged(object sender, EventArgs e) => _current = _defaultRazorViewEngineFactory();
private void PureLiveModelFactory_ModelsChanged(object sender, EventArgs e)
{
//var cache = (Microsoft.Extensions.Caching.Memory.MemoryCache)ViewLookupCache;
//// clear 100% of the cache.
//// TODO: This seems to work but need to verify
//cache.Compact(100);
_current = _defaultRazorViewEngineFactory();
}
public RazorPageResult FindPage(ActionContext context, string pageName) => _current.FindPage(context, pageName);
@@ -239,31 +311,31 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
public ViewEngineResult GetView(string executingFilePath, string viewPath, bool isMainPage) => _current.GetView(executingFilePath, viewPath, isMainPage);
}
// The default view compiler creates the compiler once and only once. That compiler will have a stale list of references
// to build against so it needs to be re-created. The only way to do that due to internals is to wrap it and re-create
// the default instance therefore resetting the compiler references.
// TODO: Find out if we really need to clear this cache or not? Or if just clearing the view engine cache is enough?
internal class RefreshingRuntimeViewCompilerProvider : IViewCompilerProvider
{
private IViewCompilerProvider _current;
private readonly Func<IViewCompilerProvider> _defaultViewCompilerProviderFactory;
private readonly PureLiveModelFactory _pureLiveModelFactory;
//// The default view compiler creates the compiler once and only once. That compiler will have a stale list of references
//// to build against so it needs to be re-created. The only way to do that due to internals is to wrap it and re-create
//// the default instance therefore resetting the compiler references.
//// TODO: Find out if we really need to clear this cache or not? Or if just clearing the view engine cache is enough?
//internal class RefreshingRuntimeViewCompilerProvider : IViewCompilerProvider
//{
// private IViewCompilerProvider _current;
// private readonly Func<IViewCompilerProvider> _defaultViewCompilerProviderFactory;
// private readonly PureLiveModelFactory _pureLiveModelFactory;
public RefreshingRuntimeViewCompilerProvider(
Func<IViewCompilerProvider> defaultViewCompilerProviderFactory,
PureLiveModelFactory pureLiveModelFactory)
{
_defaultViewCompilerProviderFactory = defaultViewCompilerProviderFactory;
_pureLiveModelFactory = pureLiveModelFactory;
_current = _defaultViewCompilerProviderFactory();
_pureLiveModelFactory.ModelsChanged += PureLiveModelFactory_ModelsChanged;
}
// public RefreshingRuntimeViewCompilerProvider(
// Func<IViewCompilerProvider> defaultViewCompilerProviderFactory,
// PureLiveModelFactory pureLiveModelFactory)
// {
// _defaultViewCompilerProviderFactory = defaultViewCompilerProviderFactory;
// _pureLiveModelFactory = pureLiveModelFactory;
// _current = _defaultViewCompilerProviderFactory();
// _pureLiveModelFactory.ModelsChanged += PureLiveModelFactory_ModelsChanged;
// }
// TODO: Do we need to lock?
private void PureLiveModelFactory_ModelsChanged(object sender, EventArgs e) => _current = _defaultViewCompilerProviderFactory();
// // TODO: Do we need to lock?
// private void PureLiveModelFactory_ModelsChanged(object sender, EventArgs e) => _current = _defaultViewCompilerProviderFactory();
public IViewCompiler GetCompiler() => _current.GetCompiler();
}
// public IViewCompiler GetCompiler() => _current.GetCompiler();
//}
// TODO: Need to review this to see if this service is actually one we need to clear or not?
// Does it hold cache? etc... I originally said "so that all of the underlying services are cleared"
@@ -310,6 +382,18 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
public override IReadOnlyList<IRazorProjectEngineFeature> ProjectFeatures => _current.ProjectFeatures;
public override RazorCodeDocument Process(RazorProjectItem projectItem) => base.Process(projectItem);
public override RazorCodeDocument Process(RazorSourceDocument source, string fileKind, IReadOnlyList<RazorSourceDocument> importSources, IReadOnlyList<TagHelperDescriptor> tagHelpers) => base.Process(source, fileKind, importSources, tagHelpers);
public override RazorCodeDocument ProcessDeclarationOnly(RazorProjectItem projectItem) => base.ProcessDeclarationOnly(projectItem);
public override RazorCodeDocument ProcessDeclarationOnly(RazorSourceDocument source, string fileKind, IReadOnlyList<RazorSourceDocument> importSources, IReadOnlyList<TagHelperDescriptor> tagHelpers) => base.ProcessDeclarationOnly(source, fileKind, importSources, tagHelpers);
public override RazorCodeDocument ProcessDesignTime(RazorProjectItem projectItem) => base.ProcessDesignTime(projectItem);
public override RazorCodeDocument ProcessDesignTime(RazorSourceDocument source, string fileKind, IReadOnlyList<RazorSourceDocument> importSources, IReadOnlyList<TagHelperDescriptor> tagHelpers) => base.ProcessDesignTime(source, fileKind, importSources, tagHelpers);
// TODO: Do we need to lock?
private void PureLiveModelFactory_ModelsChanged(object sender, EventArgs e) => _current = CreateNew();
@@ -377,7 +461,6 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
protected override void ProcessCore(RazorCodeDocument codeDocument)
=> _processCore.Invoke(_current, new[] { codeDocument });
}
/// <summary>
@@ -390,7 +473,7 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
/// So in order to have multiple, we need to have a wrapper.
/// </para>
/// </remarks>
public class MetadataReferenceFeatureWrapper : IMetadataReferenceFeature
internal class MetadataReferenceFeatureWrapper : IMetadataReferenceFeature
{
private readonly IReadOnlyList<IMetadataReferenceFeature> _metadataReferenceFeatures;
private RazorEngine _engine;
@@ -421,42 +504,48 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
}
/// <summary>
/// A custom <see cref="IMetadataReferenceFeature"/> that will dynamically resolve a reference for razor based on the current PureLive assembly.
/// A custom <see cref="IMetadataReferenceFeature"/> that will dynamically resolve a reference for razor (tag helpers) based on the current PureLive assembly.
/// </summary>
/// <remarks>
/// <para>
/// The default implementation of IMetadataReferenceFeature is https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/Mvc.Razor.RuntimeCompilation/src/LazyMetadataReferenceFeature.cs
/// which uses a ReferenceManager https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/Mvc.Razor.RuntimeCompilation/src/RazorReferenceManager.cs
/// to resolve it's references. This is done using ApplicationParts which would be nice and simple to use if we could, but the Razor engine ONLY works
/// with application part assemblies that have physical files with physical paths. We don't want to load in our PureLive assemblies on physical paths because
/// those files will be locked. Instead we load them in via bytes but this is not supported and we'll get an exception if we add them to application parts.
/// The other problem with LazyMetadataReferenceFeature is that it doesn't support dynamic assemblies, it will just check what in application parts once and
/// that's it which will not work for us in Pure Live.
/// </para>
/// </remarks>
internal class PureLiveMetadataReferenceFeature : IMetadataReferenceFeature
{
// TODO: Even though I was hoping this would work and this does allow you to return a metadata reference dynamically at runtime, it doesn't make any
// difference because the CSharpCompiler for razor only loads in it's references one time based on the initial reference checks:
// https://github.com/dotnet/aspnetcore/blob/100ab02ea0214d49535fa56f33a77acd61fe039c/src/Mvc/Mvc.Razor.RuntimeCompilation/src/CSharpCompiler.cs#L84
// Since ReferenceManager resolves them once lazily and that's it.
/*
* TODO:
* This is the only public API available to 'refresh' without hacking is the IMetadataReferenceFeature but
* it's not clear what this does since it's only used by a single service in aspnetcore.
* It is not responsible for recompiling views, but is for tag helpers.
* Used in the CompilationTagHelperFeature which ends up setting the 'Compilation' on the TagDescriptorProviderContext and
* the result of GetDescriptors() is used in the DefaultRazorTagHelperBinderPhase.
* This is all about compiling tag helpers.
* So am thinking we'll need to 'refresh' this feature as well as the normal razor views.
*/
private readonly PureLiveModelFactory _pureLiveModelFactory;
private MetadataReference[] _pureLiveReferences;
public PureLiveMetadataReferenceFeature(PureLiveModelFactory pureLiveModelFactory) => _pureLiveModelFactory = pureLiveModelFactory;
public PureLiveMetadataReferenceFeature(PureLiveModelFactory pureLiveModelFactory)
{
_pureLiveModelFactory = pureLiveModelFactory;
_pureLiveModelFactory.ModelsChanged += PureLiveModelFactory_ModelsChanged;
}
/// <inheritdoc/>
public IReadOnlyList<MetadataReference> References
{
get
{
// TODO: This won't really work based on how the CSharp compiler works
//if (_pureLiveModelFactory.CurrentModelsMetadataReference != null)
//{
// //var reference = MetadataReference.CreateFromStream(null);
// //reference.
// return new[] { _pureLiveModelFactory.CurrentModelsMetadataReference };
//}
// return the reference if we have one
if (_pureLiveReferences != null)
{
return _pureLiveReferences;
}
// else check if we need to create the reference
if (_pureLiveModelFactory.CurrentModelsMetadataReference != null)
{
_pureLiveReferences = new[] { _pureLiveModelFactory.CurrentModelsMetadataReference };
return _pureLiveReferences;
}
return Array.Empty<MetadataReference>();
}
@@ -464,5 +553,11 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection
/// <inheritdoc/>
public RazorEngine Engine { get; set; }
/// <summary>
/// When the models change, clear our references
/// </summary>
// TODO: Determine what happens without locking this, will it matter?
private void PureLiveModelFactory_ModelsChanged(object sender, EventArgs e) => _pureLiveReferences = null;
}
}

View File

@@ -126,7 +126,7 @@ namespace Umbraco.ModelsBuilder.Embedded
return _roslynCompiler;
}
_roslynCompiler = new RoslynCompiler(System.Runtime.Loader.AssemblyLoadContext.All.SelectMany(x => x.Assemblies));
_roslynCompiler = new RoslynCompiler(AssemblyLoadContext.All.SelectMany(x => x.Assemblies));
return _roslynCompiler;
}
}
@@ -438,14 +438,15 @@ namespace Umbraco.ModelsBuilder.Embedded
// as long as theres a reference to the assembly load context we can't delete the assembly it loaded
_currentAssemblyLoadContext = new UmbracoAssemblyLoadContext();
// We cannot use in-memory assemblies due to the way the razor engine works which must use
// NOTE: We cannot use in-memory assemblies due to the way the razor engine works which must use
// application parts in order to add references to it's own CSharpCompiler.
// These parts must have real paths since that is how the references are loaded. In that
// case we'll need to work on temp files so that the assembly isn't locked.
// Get a temp file path
// TODO: Not sure if the process always has access to a temp path?
var tempFile = Path.GetTempFileName();
// NOTE: We cannot use Path.GetTempFileName(), see this issue:
// https://github.com/dotnet/AspNetCore.Docs/issues/3589 which can cause issues, this is recommended instead
var tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
File.Copy(pathToAssembly, tempFile, true);
// Load it in
@@ -454,17 +455,6 @@ namespace Umbraco.ModelsBuilder.Embedded
// Create a metadata ref
metadataReference = CreateMetadataReference(tempFile);
//// Use filestream to load in the new assembly, otherwise it'll be locked
//// See https://www.strathweb.com/2019/01/collectible-assemblies-in-net-core-3-0/ for more info
//using (var fs = new FileStream(pathToAssembly, FileMode.Open, FileAccess.Read))
//{
// assembly = _currentAssemblyLoadContext.LoadFromStream(fs);
// // reset stream so it can be used for the reference (the call to CreateMetadataReference will close the stream)
// fs.Position = 0;
// metadataReference = CreateMetadataReference(fs, pathToAssembly);
//}
// Add the assembly to the application parts - this is required because this is how
// the razor ReferenceManager resolves what to load, see
// https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/Mvc.Razor.RuntimeCompilation/src/RazorReferenceManager.cs#L53

View File

@@ -1,87 +1,90 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>Umbraco.Web.UI.NetCore</RootNamespace>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>Umbraco.Web.UI.NetCore</RootNamespace>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DocumentationFile>bin\Release\Umbraco.Web.UI.NetCore.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup>
<CopyRazorGenerateFilesToPublishDirectory>true</CopyRazorGenerateFilesToPublishDirectory>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Umbraco.ModelsBuilder.Embedded\Umbraco.ModelsBuilder.Embedded.csproj" />
<ProjectReference Include="..\Umbraco.PublishedCache.NuCache\Umbraco.PublishedCache.NuCache.csproj" />
<ProjectReference Include="..\Umbraco.Web.BackOffice\Umbraco.Web.BackOffice.csproj" />
<ProjectReference Include="..\Umbraco.Web.Common\Umbraco.Web.Common.csproj" />
<ProjectReference Include="..\Umbraco.Web.Website\Umbraco.Web.Website.csproj" />
<ProjectReference Include="..\Umbraco.Persistance.SqlCe\Umbraco.Persistance.SqlCe.csproj" Condition="'$(OS)' == 'Windows_NT'" />
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DocumentationFile>bin\Release\Umbraco.Web.UI.NetCore.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup>
<CopyRazorGenerateFilesToPublishDirectory>true</CopyRazorGenerateFilesToPublishDirectory>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Umbraco.ModelsBuilder.Embedded\Umbraco.ModelsBuilder.Embedded.csproj" />
<ProjectReference Include="..\Umbraco.PublishedCache.NuCache\Umbraco.PublishedCache.NuCache.csproj" />
<ProjectReference Include="..\Umbraco.Web.BackOffice\Umbraco.Web.BackOffice.csproj" />
<ProjectReference Include="..\Umbraco.Web.Common\Umbraco.Web.Common.csproj" />
<ProjectReference Include="..\Umbraco.Web.Website\Umbraco.Web.Website.csproj" />
<ProjectReference Include="..\Umbraco.Persistance.SqlCe\Umbraco.Persistance.SqlCe.csproj" Condition="'$(OS)' == 'Windows_NT'" />
</ItemGroup>
<ItemGroup>
<Folder Include="App_Plugins" />
<Folder Include="scripts" />
<Folder Include="umbraco\MediaCache\2\c\6\9\3\a\6\5" />
<Folder Include="umbraco\MediaCache\a\e\e\1\9\e\4\b" />
<Folder Include="umbraco\MediaCache\c\3\b\5\0\9\f\9" />
<Folder Include="Views" />
<Folder Include="wwwroot\Media" />
<Folder Include="Views" />
<Folder Include="wwwroot\Media" />
</ItemGroup>
<ItemGroup>
<Folder Include="App_Plugins" />
<Folder Include="scripts" />
<Folder Include="umbraco\MediaCache\2\c\6\9\3\a\6\5" />
<Folder Include="umbraco\MediaCache\a\e\e\1\9\e\4\b" />
<Folder Include="umbraco\MediaCache\c\3\b\5\0\9\f\9" />
<Folder Include="Views" />
<Folder Include="wwwroot\Media" />
<Folder Include="Views" />
<Folder Include="wwwroot\Media" />
</ItemGroup>
<ItemGroup>
<Compile Remove="wwwroot\Umbraco\**" />
<Compile Remove="App_Data\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="wwwroot\Umbraco\**" />
<Compile Remove="App_Data\**" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Remove="App_Data\**" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Remove="App_Data\**" />
</ItemGroup>
<ItemGroup>
<Content Remove="App_Data\**" />
<Content Remove="wwwroot\Web.config" />
</ItemGroup>
<ItemGroup>
<Content Remove="App_Data\**" />
<Content Remove="wwwroot\Web.config" />
</ItemGroup>
<ItemGroup>
<None Include="config\**\*.*">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</None>
<None Include="umbraco\**\*.*">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</None>
<None Remove="App_Data\**" />
<None Include="umbraco\UmbracoWebsite\NoNodes.cshtml" />
<None Remove="scripts\aaa\fc75309db05f41609a9e1adb8cf0998c.tmp" />
</ItemGroup>
<ItemGroup>
<None Include="config\**\*.*">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</None>
<None Include="umbraco\**\*.*">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</None>
<None Remove="App_Data\**" />
<None Include="umbraco\UmbracoWebsite\NoNodes.cshtml" />
<None Remove="scripts\aaa\fc75309db05f41609a9e1adb8cf0998c.tmp" />
</ItemGroup>
<!-- We don't want to include the generated files, they will throw a lot of errors -->
<ItemGroup>
<None Remove="umbraco\Models\all.generated.cs" />
<Compile Remove="umbraco\Models\all.generated.cs" />
<None Remove="umbraco\Models\models.generated.cs" />
<Compile Remove="umbraco\Models\models.generated.cs" />
<Folder Remove="umbraco\Models\Compiled" />
<None Remove="umbraco\Models\Compiled\**" />
<None Remove="umbraco\Models\all.dll.path" />
<None Remove="umbraco\Models\models.hash" />
<None Remove="umbraco\Models\models.err" />
</ItemGroup>
<!-- We don't want to include the generated files, they will throw a lot of errors -->
<ItemGroup>
<None Remove="umbraco\Models\all.generated.cs" />
<Compile Remove="umbraco\Models\all.generated.cs" />
<None Remove="umbraco\Models\models.generated.cs" />
<Compile Remove="umbraco\Models\models.generated.cs" />
<Folder Remove="umbraco\Models\Compiled" />
<None Remove="umbraco\Models\Compiled\**" />
<None Remove="umbraco\Models\all.dll.path" />
<None Remove="umbraco\Models\models.hash" />
<None Remove="umbraco\Models\models.err" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.8" />
<!-- TODO: remove the reference to System.Configuration.ConfigurationManager when Examine/lucene dont need it-->
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.7.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.8" />
<!-- TODO: remove the reference to System.Configuration.ConfigurationManager when Examine/lucene dont need it-->
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.7.0" />
</ItemGroup>
<PropertyGroup>
<RazorCompileOnBuild>false</RazorCompileOnBuild>
</PropertyGroup>
</Project>

View File

@@ -67,7 +67,7 @@
},
"ModelsBuilder": {
"ModelsMode": "PureLive",
"Enable": false
"Enable": true
}
}
}