ASP.NET MVC 3 RC AreaRegistration.RegisterAllAreas() and dynamically loaded assemblies

前端 未结 2 445
难免孤独
难免孤独 2020-12-24 15:16

I am currently experimenting with dynamically loaded areas with ASP.NET MVC 3 RC. I\'ve seen it written in many places that this is not what areas are intended for, and (at

2条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-24 16:00

    1 - Seperate you Mvc Areas into differrent Mvc Projects to be compiled into their own seperate assemblies

    2 - Add this to your AssemblyInfo.cs class, to call a method when the application is loaded

    [assembly: PreApplicationStartMethod(typeof(PluginAreaBootstrapper), "Init")]
    

    3 - Here's what the Init method looks like when it's invoked during the load

    public class PluginAreaBootstrapper
    {
        public static readonly List PluginAssemblies = new List();
    
        public static List PluginNames()
        {
            return PluginAssemblies.Select(
                pluginAssembly => pluginAssembly.GetName().Name)
                .ToList();
        }
    
        public static void Init()
        {
            var fullPluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Areas");
    
            foreach (var file in Directory.EnumerateFiles(fullPluginPath, "*Plugin*.dll"))
                PluginAssemblies.Add(Assembly.LoadFile(file));
    
            PluginAssemblies.ForEach(BuildManager.AddReferencedAssembly);
        }
    }
    

    4 - Add a custom RazorViewEngine

    public class PluginRazorViewEngine : RazorViewEngine
    {
        public PluginRazorViewEngine()
        {
            AreaMasterLocationFormats = new[]
            {
                "~/Areas/{2}/Views/{1}/{0}.cshtml",
                "~/Areas/{2}/Views/{1}/{0}.vbhtml",
                "~/Areas/{2}/Views/Shared/{0}.cshtml",
                "~/Areas/{2}/Views/Shared/{0}.vbhtml"
            };
    
            AreaPartialViewLocationFormats = new[]
            {
                "~/Areas/{2}/Views/{1}/{0}.cshtml",
                "~/Areas/{2}/Views/{1}/{0}.vbhtml",
                "~/Areas/{2}/Views/Shared/{0}.cshtml",
                "~/Areas/{2}/Views/Shared/{0}.vbhtml"
            };
    
            var areaViewAndPartialViewLocationFormats = new List
            {
                "~/Areas/{2}/Views/{1}/{0}.cshtml",
                "~/Areas/{2}/Views/{1}/{0}.vbhtml",
                "~/Areas/{2}/Views/Shared/{0}.cshtml",
                "~/Areas/{2}/Views/Shared/{0}.vbhtml"
            };
    
            var partialViewLocationFormats = new List
            {
                "~/Views/{1}/{0}.cshtml",
                "~/Views/{1}/{0}.vbhtml",
                "~/Views/Shared/{0}.cshtml",
                "~/Views/Shared/{0}.vbhtml"
            };
    
            var masterLocationFormats = new List
            {
                "~/Views/{1}/{0}.cshtml",
                "~/Views/{1}/{0}.vbhtml",
                "~/Views/Shared/{0}.cshtml",
                "~/Views/Shared/{0}.vbhtml"
            };
    
            foreach (var plugin in PluginAreaBootstrapper.PluginNames())
            {
                masterLocationFormats.Add(
                    "~/Areas/" + plugin + "/Views/{1}/{0}.cshtml");
                masterLocationFormats.Add(
                    "~/Areas/" + plugin + "/Views/{1}/{0}.vbhtml");
                masterLocationFormats.Add(
                    "~/Areas/" + plugin + "/Views/Shared/{1}/{0}.cshtml");
                masterLocationFormats.Add(
                    "~/Areas/" + plugin + "/Views/Shared/{1}/{0}.vbhtml");
    
                partialViewLocationFormats.Add(
                    "~/Areas/" + plugin + "/Views/{1}/{0}.cshtml");
                partialViewLocationFormats.Add(
                    "~/Areas/" + plugin + "/Views/{1}/{0}.vbhtml");
                partialViewLocationFormats.Add(
                    "~/Areas/" + plugin + "/Views/Shared/{0}.cshtml");
                partialViewLocationFormats.Add(
                    "~/Areas/" + plugin + "/Views/Shared/{0}.vbhtml");
    
                areaViewAndPartialViewLocationFormats.Add(
                    "~/Areas/" + plugin + "/Views/{1}/{0}.cshtml");
                areaViewAndPartialViewLocationFormats.Add(
                    "~/Areas/" + plugin + "/Views/{1}/{0}.vbhtml");
                areaViewAndPartialViewLocationFormats.Add(
                    "~/Areas/" + plugin + "/Areas/{2}/Views/{1}/{0}.cshtml");
                areaViewAndPartialViewLocationFormats.Add(
                    "~/Areas/" + plugin + "/Areas/{2}/Views/{1}/{0}.vbhtml");
                areaViewAndPartialViewLocationFormats.Add(
                    "~/Areas/" + plugin + "/Areas/{2}/Views/Shared/{0}.cshtml");
                areaViewAndPartialViewLocationFormats.Add(
                    "~/Areas/" + plugin + "/Areas/{2}/Views/Shared/{0}.vbhtml");
            }
    
            ViewLocationFormats = partialViewLocationFormats.ToArray();
            MasterLocationFormats = masterLocationFormats.ToArray();
            PartialViewLocationFormats = partialViewLocationFormats.ToArray();
            AreaPartialViewLocationFormats = areaViewAndPartialViewLocationFormats.ToArray();
            AreaViewLocationFormats = areaViewAndPartialViewLocationFormats.ToArray();
        }
    }
    

    5 - Register your Areas from your different Mvc (Area) Projects

    namespace MvcApplication8.Web.MyPlugin1
    {
        public class MyPlugin1AreaRegistration : AreaRegistration
        {
            public override string AreaName
            {
                get { return "MyPlugin1"; }
            }
    
            public override void RegisterArea(AreaRegistrationContext context)
            {
                context.MapRoute(
                    "MyPlugin1_default",
                    "MyPlugin1/{controller}/{action}/{id}",
                    new {action = "Index", id = UrlParameter.Optional}
                    );
            }
        }
    }
    

    Sourcecode and additional references can can be found here:http://blog.longle.io/2012/03/29/building-a-composite-mvc3-application-with-pluggable-areas

提交回复
热议问题