2011-08-25 82 views
0

我正在研究一个与MVC3一起工作的插件系统,DLL被放置在〜/ Plugin /目录中。到目前为止,当主机发现模型和控制器并且视图正确地嵌入到DLL中时,所有的工作都很好并且很花哨。唯一的问题是视图不能被Razor引擎编译。MVC3插件系统

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

+0

不要击落任何东西,但你有没有考虑过使用FubuMVC?它的目标是能够通过一个名为Bottles的概念来添加新的东西。 –

回答

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); 
    }