I have an ASP.NET Core 6 MVC application which is loading in controllers and views from an external project. The project assemblies are dynamically loaded in rather than by project reference.
I am using application parts for registering the assembly as described here and looks like the following in my Startup.ConfigureServices
method:
var externalControllerAssemblies = GetExternalMvcControllerAssemblies();
services.Configure<MvcRazorRuntimeCompilationOptions>(options =>
{
foreach (var assembly in externalControllerAssemblies)
{
options.FileProviders.Add(new EmbeddedFileProvider(assembly));
}
});
var mvcBuilder = services.AddMvc();
foreach (var assembly in externalControllerAssemblies)
{
mvcBuilder.AddApplicationPart(assembly);
}
mvcBuilder
.AddRazorRuntimeCompilation()
.AddControllersAsServices();
services.AddControllersWithViews();
services.AddRazorPages()
When I run up the site I can see that the controller and views have been loaded and can navigate to the views. However, if the view has a reference to a model in the same project then I see a the following type of error:
An error occurred during the compilation of a resource required to process this request. Please review the following specific error details and modify your source code appropriately.
Generated Code
One or more compilation references may be missing. If you're seeing this in a published application, set 'CopyRefAssembliesToPublishDirectory' to true in your project file to ensure files in the refs directory are published.
The type or namespace name 'WebPlugin' could not be found (are you missing a using directive or an assembly reference?)
public class _Views_Area_MyView : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<WebPlugin.Models.Area.MyViewModel>
The type or namespace name 'WebPlugin' could not be found (are you missing a using directive or an assembly reference?)
public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<WebPlugin.Models.Models.Area.MyViewModel> Html { get; private set; }
It's as if the hosting app hasn't got the model types loaded into the application domain even though the assembly has been loaded. Has anyone got any ideas as to how this can be resolved?
Turns out if I hit enough keys eventually I'll get the right answer.
Adding reference paths to the RazorRuntimeCompilation options seems to have done the trick..
mvcBuilder
.AddRazorRuntimeCompilation()
.AddControllersAsServices()
.AddRazorRuntimeCompilation(options => {
externalControllerAssemblies.ForEach(assembly =>
{
options.AdditionalReferencePaths.Add(assembly.Location);
});
});