C# MVC3插件系统

C# MVC3插件系统,c#,asp.net-mvc-3,C#,Asp.net Mvc 3,我正在开发一个使用MVC3的插件系统,DLL被放在~/plugin/目录中。到目前为止,由于主机找到了模型和控制器,并且视图正确地嵌入到DLL中,所以一切都正常工作。唯一的问题是Razor引擎无法编译视图 在应用程序的初始化阶段添加模型和控制器,如下所示: [assembly: PreApplicationStartMethod(typeof(Dashboard.PluginReader), "Initialize")] namespace Dashboard { public clas

我正在开发一个使用MVC3的插件系统,DLL被放在~/plugin/目录中。到目前为止,由于主机找到了模型和控制器,并且视图正确地嵌入到DLL中,所以一切都正常工作。唯一的问题是Razor引擎无法编译视图

在应用程序的初始化阶段添加模型和控制器,如下所示:

[assembly: PreApplicationStartMethod(typeof(Dashboard.PluginReader), "Initialize")]
namespace Dashboard
{
    public class PluginReader
    {
        public static void Initialize()
        {
            foreach (string plugin in Directory.GetFiles(HostingEnvironment.MapPath("~/Plugin"), "*.dll", SearchOption.AllDirectories))
            {
                Assembly assembly = Assembly.LoadFile(plugin);
                BuildManager.AddReferencedAssembly(assembly);
            }
        }
    }
}
class AssemblyResourceVirtualFile : VirtualFile
{
    string path;
    public AssemblyResourceVirtualFile(string virtualPath)
        : base(virtualPath)
    {
        path = VirtualPathUtility.ToAppRelative(virtualPath);
    }
    public override System.IO.Stream Open()
    {
        // /~Plugin/path.of.dll/path.of.razor.view
        string[] parts = path.Split('/');
        string assemblyName = parts[2];
        string resourceName = parts[3];

        string path = HostingEnvironment.MapPath("~/Plugin") + "/"+ assemblyName;

        System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFile(path);
        if (assembly != null)
        {
            Stream resourceStream = assembly.GetManifestResourceStream(resourceName);
            return resourceStream;
        }
        return null;
    }
}
为了解析视图,我使用VirtualFile和VirtualPathProvider,它们以流的形式返回请求的资源,如下所示:

[assembly: PreApplicationStartMethod(typeof(Dashboard.PluginReader), "Initialize")]
namespace Dashboard
{
    public class PluginReader
    {
        public static void Initialize()
        {
            foreach (string plugin in Directory.GetFiles(HostingEnvironment.MapPath("~/Plugin"), "*.dll", SearchOption.AllDirectories))
            {
                Assembly assembly = Assembly.LoadFile(plugin);
                BuildManager.AddReferencedAssembly(assembly);
            }
        }
    }
}
class AssemblyResourceVirtualFile : VirtualFile
{
    string path;
    public AssemblyResourceVirtualFile(string virtualPath)
        : base(virtualPath)
    {
        path = VirtualPathUtility.ToAppRelative(virtualPath);
    }
    public override System.IO.Stream Open()
    {
        // /~Plugin/path.of.dll/path.of.razor.view
        string[] parts = path.Split('/');
        string assemblyName = parts[2];
        string resourceName = parts[3];

        string path = HostingEnvironment.MapPath("~/Plugin") + "/"+ assemblyName;

        System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFile(path);
        if (assembly != null)
        {
            Stream resourceStream = assembly.GetManifestResourceStream(resourceName);
            return resourceStream;
        }
        return null;
    }
}

Razor编译它们时会返回一个异常,因为它找不到诸如ViewBag之类的引用。有人知道如何让这些嵌入式资源工作,或者知道现有的插件系统吗?

下面的文章看起来非常有用
回答

如果您想制作这样的插件,只需执行以下操作:

  • 按照Chris van de Steeg网站上的说明进行操作
  • 将控制器也复制到类库中
  • 复制pluginator类。DLL需要在bin或GAC中才能工作
最后,将其放在应用程序_Start()中


不击落任何东西,但你考虑过使用FubuMVC吗?它的目标是通过一个叫做瓶子的概念来添加新的东西。这就成功了,如果你想制作这样的插件,你只需要做以下事情:复制插件。DLL需要在bin或GAC中才能工作。