MVC3插件系统

时间:2011-08-25 18:14:56

标签: c# asp.net-mvc-3

我正在开发一个与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);
            }
        }
    }
}

为了解析视图,我使用VirtualFile和VirtualPathProvider,它将请求的资源作为流返回:

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这样的引用。有没有人知道如何使这些嵌入式资源工作或知道现有的插件系统?

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

<强>答案

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

最后,将其放在Application_Start()。

    protected void Application_Start()
    {
        foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            // As you can see, it checks if the assembly has plugin in it's name
            // If you want something more solid, replace it at will
            if (assembly.ManifestModule.Name.ToLower().Contains("plugin"))
            {
                BoC.Web.Mvc.PrecompiledViews.ApplicationPartRegistry.Register(assembly);
            }
        }

        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }