使用编译时未知的 ViewComponent

Using a ViewComponent not known at compile time

我正在开始一个新的 ASP.Net MVC 核心项目,我正在尝试弄清楚如何执行以下操作:

我希望能够添加 "plugins" 的应用程序的一部分,这在编译时是未知的。我有一个页面,我想在其中添加一个可以来自外部来源的 "component"。

例如,我有一个包含基本信息的页面。假设我正在构建房屋销售软件。我有关于所有人都相同的房屋的基本信息,但我有一个下拉列表,根据现有的插件和其他信息,在页面上显示一个在编译时不一定知道的组件。

我看过ViewComponents,不过好像和Partial Views有点类似,使用InvokeAsync好像意味着编译时就得知道了。

此外,您将如何存储这些 ViewComponents 的数据?

视图组件不需要在编译时就知道。它们可以在运行时被引用,但有一些技巧。首先,需要将 class 库中的 cshtml 文件作为嵌入资源包含在内。这可以通过将以下内容添加到 class 库的 project.json 来完成:

"buildOptions": {
   "embed": "Views/**/*.cshtml"
}

在您的网络应用程序的 Startup.ConfigureServices 方法中,您需要向 RazorViewEngineOptions 添加一个嵌入式文件提供程序。这是一个为已知程序集执行此操作的示例。

    //Get a reference to the assembly that contains the view components
var assembly = typeof(ViewComponentLibrary.ViewComponents.SimpleViewComponent).GetTypeInfo().Assembly;

//Create an EmbeddedFileProvider for that assembly
var embeddedFileProvider = new EmbeddedFileProvider(
    assembly,
    "ViewComponentLibrary"
);

//Add the file provider to the Razor view engine
services.Configure<RazorViewEngineOptions>(options =>
{                
    options.FileProviders.Add(embeddedFileProvider);
});

在您的情况下,您需要动态加载这些程序集,这可以使用 AssemblyLoadContext.Default.LoadFromAssemblyPath 为插件目录中找到的每个程序集来完成。

var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyPath);

如果不了解您的应用程序和特定用例,很难回答如何为视图组件存储数据的问题。

我在博客 post 中概述了使用来自 class 库的视图组件的过程:http://www.davepaquette.com/archive/2016/07/16/loading-view-components-from-a-class-library-in-asp-net-core.aspx