我正在使用Razor视图为ASP.NET MVC3设计一个插件框架,我遇到了使嵌入式视图正常工作的问题。
插件框架旨在具备以下功能:
现在一切正常,除非嵌入视图引用了插件dll中的类型。然后我得到臭名昭着的错误(名字遗漏):
The type or namespace name '[Plugins]' does not exist in the namespace '[MyPluginSolution]' (are you missing an assembly reference?)
原因是调用运行时编译剃刀视图的csc编译器只从bin文件夹和GAC获取dll引用。
我也尝试使用this technique预编译视图,但最后它给出了相同的结果,因为运行时坚持为预编译的剃刀视图编译包装器。
我当然可以将插件dll放在/ bin文件夹中,但我的问题是:
有没有办法在非bin(和非GAC)文件夹中注册dll,并将它们视为“一等公民”,以便剃刀视图可以使用它们? < / p>
答案 0 :(得分:14)
好的,使用this article找到了解决方案。
首先,我使用 PreApplicationStartMethod
创建一个类。此方法扫描插件文件夹并将dll复制到AppDomain.DynamicDirectory
。
然后使用 BuildManager.AddReferencedAssembly
加载每个dll。
而且,强烈类型的Razor视图编译得很漂亮。请参阅此处的代码:
[assembly: PreApplicationStartMethod(typeof(MySolution.PluginHandler.PluginActivator), "Initialize")]
namespace MySolution.PluginHandler
{
public class PluginActivator
{
private static readonly DirectoryInfo PluginFolderInfo;
static PluginActivator() {
PluginFolderInfo = new DirectoryInfo(HostingEnvironment.MapPath("~/plugins"));
}
public static void Initialize() {
CopyPluginDlls(PluginFolderInfo, AppDomain.CurrentDomain.DynamicDirectory);
LoadPluginAssemblies(AppDomain.CurrentDomain.DynamicDirectory);
}
private static void CopyPluginDlls(DirectoryInfo sourceFolder, string destinationFolder)
{
foreach (var plug in sourceFolder.GetFiles("*.dll", SearchOption.AllDirectories)) {
if (!File.Exists(Path.Combine(destinationFolder, plug.Name))) {
File.Copy(plug.FullName, Path.Combine(destinationFolder, plug.Name), false);
}
}
}
private static void LoadPluginAssemblies(string dynamicDirectory)
{
foreach (var plug in Directory.GetFiles(dynamicDirectory, "*.dll", SearchOption.AllDirectories)) {
Assembly assembly = Assembly.Load(AssemblyName.GetAssemblyName(plug));
BuildManager.AddReferencedAssembly(assembly);
}
}
}
}
我希望这可以帮助其他想要使用这些新技术创建一个干净的插件框架的程序员。
答案 1 :(得分:1)
David Ebbo最近发表了关于将Razor视图预编译到程序集中的博文。您可以查看帖子here。
您应该能够通过动态加载程序集来避免直接注册程序集(我通常会使用我的IoC容器),然后为每个插件程序集调用BuildManager.AddReferencedAssembly。
答案 2 :(得分:1)
查看MEF
你也可以和温莎安装人员一起做这件事 - 迈克哈德洛对此很好:http://mikehadlow.blogspot.com/2010/10/experimental-aspnet-mvc-add-ins-updated.html
答案 3 :(得分:1)
请查看NOPCommerce源代码。它有一个很好的插件框架,基于Shannon的工作。
答案 4 :(得分:1)
您还可以在MVC3和4中使用“区域”功能,您可以创建一个不错的插件系统。它将处理插件的模型,视图和控制器分离在它自己的程序集中。
答案 5 :(得分:0)
您可能会发现这有用http://www.adverseconditionals.com/2011/07/portable-aspnet-code-using.html
我已经开始创建两个项目
在MyLibrary MyLibrary.Templates
并在.Templates中将视图作为内容添加,并添加为链接并设置为MyLibrary中的EmbeddedResource。想要覆盖视图的人可以安装.Templates项目。