如何在运行时引用mvc中的汇编
本文关键字:汇编 mvc 引用 运行时 | 更新日期: 2023-09-27 18:00:21
在我的Asp.Net MVC应用程序中,我有一些视图文件(.cshtml
),它引用了一个外部库,它将在运行时加载。所以在应用程序启动后,我通过assembly加载程序集。加载并通过我自己的自定义ControllerFactory
注册控制器,一切都很好。
但是,在某些引用了动态加载的程序集的视图中,会抛出:
编译器错误消息:CS0234:命名空间"MyApp"中不存在类型或命名空间名称"MyDynamicNamespace"(是否缺少程序集引用?)
告诉剃刀编译器无法解析相关程序集的异常。
我的问题是,有没有一种方法可以在运行时注册程序集,以便剃刀编译器能够访问并解决它?
注意我不能使用BuildManager.AddReferencedAssembly
方法,因为我的程序集必须在应用程序启动后加载,而BuildManager
不支持它。
1)我不建议您的视图直接使用外部引用或动态加载的外部引用。通过让视图与控制器交互来抽象这一点。让您的控制器将一个数据对象馈送到您的视图,该数据对象在构建时由您的应用程序已知(换句话说,一个在构建时为您的web应用程序已知的对象)。这是为了将插件特定的业务与您的视图完全隔离(抽象)。然后让你的控制器与"插件"进行交互。
2) 我不知道你们的"定制工厂"是怎么运作的,但现在我们已经不再真正建造任何"定制工厂"了。相反,我们利用依赖注入容器,如Microsoft Unity(或Ninject,或Castle Windsor等)。创建"自定义工厂"是非常过时的,你基本上是在重新发明依赖注入解决的轮子。
3) 至于动态加载外部程序集,我不知道你是否正确,但这里有一个链接:
从外部程序集动态加载类型
4) 通常,插件设计会在构建时公开主web应用程序已知的接口。插件设计隐藏的是可以从一个插件更改为另一个插件的实现。重要的是,每个插件都实现了相同的公共接口,这些接口是您的主要web应用程序所期望的。通常,您将在一个单独的"Common"项目中拥有这些接口,该项目由您的主web应用程序和实现这些接口的插件引用。因此,从您的主web应用程序中,您将知道插件的公共接口是什么,您可以动态加载外部程序集,并使用C#反射来找到实现这些接口的类,并将它们加载到依赖项注入容器中。同样,任何想为你的网络应用程序开发插件的人都必须实现你的"Common"项目中定义的接口。
注意:"Common"只是我给这个项目取的一个随机名称。您可以将其命名为"PluginInterface"或任何您想要的名称。
在那之后,让控制器从依赖注入容器中获取它所需要的任何东西都是微不足道的。
注意:您的插件接口可能会有输入和输出实体。这些实体在您的主web应用程序和插件之间共享。在这种情况下,由于这些实体是接口的一部分,它们需要在"Common"项目中。你可能会想让你的控制器直接将这些实体返回到你的视图,但这样你的视图和插件之间就没有完美的抽象了。没有完美的抽象是另一种讨论。
希望它能有所帮助!
作为一名系统管理员,我建议您有一段维护期,尤其是当您替换的文件弄乱了其他文件时。即使你的保养期只有半个小时,这也是一种很好的做法。
至于DLL和重新编译。。。通常,IIS工作进程(运行应用程序池的服务)将根据IIS配置和内存使用情况以正常间隔进行回收。当这种情况发生时,如果有任何东西需要JIT,应用程序将重新编译。它还终止所有打开的用户会话,因为它在物理上停止,然后重新启动。工作进程还监视根目录(如前所述)是否有任何文件更改。如果发现任何错误,则强制重新编译。仅仅因为一个依赖项被更改并不能强制重新编译。如果预编译DLL,剩下的唯一要编译的就是实际ASPX文件中的任何代码,这将使用每次编译的JIT。根据您的描述,IIS不需要重新编译或重新启动,这听起来像是交换文件时IIS挂起的另一个问题。可能需要让系统管理员参与进来查看IIS日志。
祝你好运!
http://msdn.microsoft.com/en-us/library/ms366723.aspx
http://msdn.microsoft.com/en-us/library/bb398860.aspx
以下是一个可能有帮助的注意事项:如果您不是从/bin
目录加载程序集,则需要确保程序集的路径是可发现的:
AppDomain.CurrentDomain.AppendPrivatePath(path_to_your-dyna_assembly);