0

I'm working on a plugin system that works with MVC3, DLL's are placed in the ~/Plugin/ directory. So far everything is working fine and dandy as models and controllers are found by the host and the views are properly embedded into the DLL's. The only problem is that views cannot be compiled by the Razor engine.

Models and controllers are added during the initialization phase of the application like this:

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

In order to resolve the views I use a VirtualFile and a VirtualPathProvider which return the requested resource as stream like this:

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

As Razor compiles them it returns an exception as it cannot find the references such as ViewBag. Does anyone have an idea on how to make these embedded resources work or know an existing plugin system?

  • Not to shoot down anything but have you considered using FubuMVC? It's targeted around being able to add new things via a concept called Bottles. – Shane Courtrille Aug 25 '11 at 19:35

2 Answers2

0

The following post looks very useful for this http://www.chrisvandesteeg.nl/2010/11/22/embedding-pre-compiled-razor-views-in-your-dll/

Alex H
  • 733
  • 4
  • 8
  • That did the trick, if you want to make a plugin like this you just have to do the following: http://stackoverflow.com/questions/6465855/a-plugin-framework-with-asp-net-mvc3-and-embedded-razor-views Copy the PluginActivator. The DLL needs to be in the bin or GAC to work. –  Aug 26 '11 at 08:52
0

Answer

If you want to make a plugin like this you just do the following:

And finally, place this in the 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);
    }
Community
  • 1
  • 1