在.NET Core 2.1中动态包含预编译(Razor)视图

时间:2018-09-13 15:58:31

标签: asp.net-core .net-core asp.net-core-mvc asp.net-core-2.0

想法
我正在尝试构建模块化的.NET Core MVC应用程序,只要将所需的库复制到预定义的文件夹中即可添加“模块”(扩展名)。该应用程序定义了一组依赖项(DI),错误处理和基本布局。这些模块提供了实际的应用程序或页面逻辑。

我们使用ExtCore构建了概念验证-这个概念很好用,控制器被自动添加并且可以轻松识别“纯视图”(设置为“嵌入式资源”的视图)。

挑战
但是,我不喜欢将Views设置为“ Embedded Resource”的事实,因为Razor页面现在是在运行时生成的,因此对性能的影响不大。

我们尝试过的事情
由于.NET Core 2.1现在具有创建Reusable Razor UI的能力,因此我创建了一个引用<Project Sdk="Microsoft.NET.Sdk.Razor">的项目,并将其编译到Razor库(* .Views.dll)中。

当我在主应用程序中将Razor View库链接为项目依赖项时,一切正常。但是,目标仍然是使应用程序完全即插即用,并允许仅通过将库部署到文件夹中就可以包含库。

我尝试使用PhysicalFileProvider扩展Razor View Engine,但它无法识别库中的视图。

 services.Configure<RazorViewEngineOptions>(opt =>
 {
     opt.FileProviders.Add(new PhysicalFileProvider("path/to/extension"));
 });

结果始终是一个异常,告诉我找不到/Views/[controller]/[action].cshtml

搜索其他遇到的问题,我遇到了一个this项目,该项目创建了一个ViewLocationExpander。我尝试实现此想法的各种版本时都没有碰到运气-很有可能是因为这是基于.NET Core 1.x的较旧概念,仍然使用项目依赖项。尽管Razor View引擎现在可以搜索程序集的名称空间。

services.Configure<RazorViewEngineOptions>(opt =>
{
    opt.FileProviders.Add(new PhysicalFileProvider("path/to/extension");
    opt.ViewLocationExpanders.Add(new DynamicLocationExpander());
});

DynamicLocationExpander如下所示:

public class DynamicLocationExpander: IViewLocationExpander
{

    public DynamicLocationExpander()
    {

    }

    public void PopulateValues(ViewLocationExpanderContext context)
    {

    }

    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
    {
        string assembly = ((ControllerActionDescriptor)context.ActionContext.ActionDescriptor)
            .ControllerTypeInfo.AsType().Assembly.GetName().Name;

        foreach (var viewLocation in viewLocations)
            yield return $"{assembly}/{viewLocation}";
    }
}

问题
我们如何动态地将包含预编译视图的Razor View库链接到(父)应用程序中的Razor Engine?

0 个答案:

没有答案