unt*_*dex 11 mef dynamic-compilation strongly-typed-view razor asp.net-mvc-3
我正在构建一个使用MEF的MVC 3应用程序.主要思想是具有插件机制,其中模型,控制器和视图在运行时从mef容器动态加载.
每个插件/模块由两个程序集组成:
并放在Web应用程序bin中的Plugins目录中:
还有所有其他模块引用的核心模块:ModuleCore.Data.dll和ModuleCore.Web.dll.
然后,在Global.asax中,以下列方式构建容器:
AggregateCatalog catalog = new AggregateCatalog();
var binCatalog = new DirectoryCatalog(HttpRuntime.BinDirectory, "Module*.dll");
var pluginsCatalot = new DirectoryCatalog(Path.Combine(HttpRuntime.BinDirectory, "Plugins"), "Module*.dll");
catalog.Catalogs.Add(binCatalog);
catalog.Catalogs.Add(pluginsCatalot);
CompositionContainer container = new CompositionContainer(catalog);
container.ComposeParts(this);
AppDomain.CurrentDomain.AppendPrivatePath(Path.Combine(HttpRuntime.BinDirectory, "Plugins"));
Run Code Online (Sandbox Code Playgroud)
创建并注册CustomViewEngine并用于在模块程序集中查找视图:
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomViewEngine());
Run Code Online (Sandbox Code Playgroud)
控制器工厂从容器加载控制器:
ControllerBuilder.Current.SetControllerFactory(new MefControllerFactory(_container));
Run Code Online (Sandbox Code Playgroud)
以及从容器中获取程序集的自定义虚拟路径提供程序:
HostingEnvironment.RegisterVirtualPathProvider(new ModuleVirtualPathProvider());
Run Code Online (Sandbox Code Playgroud)
好的,所以处理可插拔模型,控制器和视图的整个基础设施已准备就绪.现在一切正常......除了一件事 - 强类型视图.
为了更详细地说明问题,让我们准备场景:
现在我们执行以下操作:
因此,似乎编译器/构建器没有查看Module1.Data.dll的bin/Plugins文件夹,因为当我将此文件复制到bin文件夹时 - 措辞很好.
问题/问题:为什么构建器没有查看bin/Plugins文件夹,即使此目录是由AppDomain.CurrentDomain.AppendPrivatePath方法添加的?如何为程序集生成器添加一次私有路径,以便考虑插件文件夹?
我已经设法通过创建覆盖标准的CustomRazorBuildProvider来做一些工作:
public class CustomRazorBuildProvider : RazorBuildProvider
{
public override void GenerateCode(System.Web.Compilation.AssemblyBuilder assemblyBuilder)
{
Assembly a = Assembly.LoadFrom(Path.Combine(HttpRuntime.BinDirectory, "Plugins", "Module1.Data.dll"));
assemblyBuilder.AddAssemblyReference(a);
base.GenerateCode(assemblyBuilder);
}
}
Run Code Online (Sandbox Code Playgroud)
但是这个解决方案的缺点是每次编译视图时,都需要添加对Plugins文件夹中所有程序集的引用,这可能会在以后使用大量插件时导致性能问题.
有更好的解决方案吗?
这是一个想法。
如果遵循视图模型模式,则不要将 DTO 直接发送到视图,而是使用与视图位于同一程序集中的 ViewModel。
所以而不是:
UserDTO 模型位于 Module1.Data.dll ShowUserController.cs 位于 Module1.Web.dll/Controllers/ Index.cshtml 位于 Module1.Web.dll/Views/ShowUser (带有声明的@model Module1.Data.UserDto)
你将会拥有:
UserDTO 模型位于 Module1.Data.dll ShowUserController.cs 位于 Module1.Web.dll/Controllers/ UserVM 位于 Module1.Web.dll/ViewModels Index.cshtml 位于 Module1.Web.dll/Views/ShowUser (与声明的@model Module1.Web.ViewModels.UserVM)
让控制器将您的 DTO 映射到 ViewModel
请参阅AutoMapper来帮助进行映射
归档时间: |
|
查看次数: |
1679 次 |
最近记录: |