Reputation: 23093
I am using the following code to dynamically load a Razor Class Library into my ASP.NET Core 3.0
app:
var pluginAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(file.FullName);
var partFactory = ApplicationPartFactory.GetApplicationPartFactory(pluginAssembly);
foreach (var part in partFactory.GetApplicationParts(pluginAssembly))
MvcBuilder.PartManager.ApplicationParts.Add(part);
var relatedAssemblies = RelatedAssemblyAttribute.GetRelatedAssemblies(pluginAssembly, throwOnError: true);
foreach (var assembly in relatedAssemblies)
{
partFactory = ApplicationPartFactory.GetApplicationPartFactory(assembly);
foreach (var part in partFactory.GetApplicationParts(assembly))
MvcBuilder.PartManager.ApplicationParts.Add(part);
}
This works fine and controllers and views are initially working. But if I also add the Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
package and the following to the Startup.cs
:
services.Configure<MvcRazorRuntimeCompilationOptions>(options =>
{
options.FileProviders.Add(new PhysicalFileProvider(Path.Combine(WebHostEnvironment.ContentRootPath, "..\\AppPlugin")));
});
I get the following exception as soon as I edit a *.cshtml
-file:
InvalidOperationException: Cannot find compilation library location for package 'AppPlugin'
- Microsoft.Extensions.DependencyModel.CompilationLibrary.ResolveReferencePaths(ICompilationAssemblyResolver resolver, List assemblies)
Microsoft.Extensions.DependencyModel.CompilationLibrary.ResolveReferencePaths()
Microsoft.AspNetCore.Mvc.ApplicationParts.AssemblyPartExtensions+<>c.b__0_0(CompilationLibrary library)
- System.Linq.Enumerable+SelectManySingleSelectorIterator.MoveNext()
- System.Collections.Generic.List.InsertRange(int index, IEnumerable collection)
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.RazorReferenceManager.GetReferencePaths()
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.RazorReferenceManager.GetCompilationReferences()
Is there something else I need to load to get this to work?
If I omit the plugin-path from the FileProviders
runtime-compilation works for "non-plugin-views".
Upvotes: 4
Views: 1553
Reputation: 23
Issue In .net6 when you use both:
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
Microsoft.VisualStudio.Web.CodeGeneration.Design
you have the error message:
Cannot find compilation library location for package 'Microsoft.Build'`
Solution
Uninstall Microsoft.VisualStudio.Web.CodeGeneration.Design
package and you'll be able to use razor runtime compile.
Upvotes: 2
Reputation: 44
If you are still missing references after defining razor runtime compilation as described in other answers and missing types are located in namespaces referenced as global using
e.g. global using MyNamespace.Extensions;
try to explicitly add your namespaces to _ViewImports.cshtml
or directly into view with @using MyNamespace.Extensions
Upvotes: 0
Reputation: 2771
I was able to get this working by using the following project settings for the razor class library. The key piece was to set PreserveCompilationContext to false.
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<PreserveCompilationContext>false</PreserveCompilationContext>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
In Addition to this, you'll have to add a reference to your main plugin assembly and any additional assemblies used in your views.
services.Configure<MvcRazorRuntimeCompilationOptions>(options =>
{
options.FileProviders.Add(new PhysicalFileProvider(Path.Combine(WebHostEnvironment.ContentRootPath, "..\\AppPlugin")));
opts.AdditionalReferencePaths.Add(pluginAssembly.Location);
});
Upvotes: 5