2011-08-25 63 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); 
    }