My goal is to modify asp.net mvc's controller registery so that I can create controllers and views in a separate (child) assembly, and just copy the View files and the DLLs to the host MVC application and the new controllers are effectively "Plugged In" to the host app.
Obviously, I will need some sort of IoC pattern, but I'm at a loss.
My thought was to have a child assembly with system.web.mvc referenced and then to just start building controller classes that inherited from Controller
:
Separate Assembly:
using System.Web; using System.Web.Mvc; namespace ChildApp { public class ChildController : Controller { ActionResult Index() { return View(); } } }
Yay all fine and dandy. But then I looked into modifying the host application's Controller registry to load my new child controller at runtime, and I got confused. Perhaps because I need a deeper understanding of C#.
Anyway, I thought I needed to create a CustomControllerFactory
class. So I started writing a class that would override the GetControllerInstance()
method. As I was typing, intellisence popped this up:
Host MVC Application:
public class CustomControllerFactory : DefaultControllerFactory { protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType) { return base.GetControllerInstance(requestContext, controllerType); } }
Now, at this point I'm at a loss. I don't know what that does. Originally, I was going to write a "Controller Loader" class like a Service Locator like this:
Host MVC Application:
public class ControllerLoader { public static IList<IController> Load(string folder) { IList<IController> controllers = new List<IController>(); // Get files in folder string[] files = Directory.GetFiles(folder, "*.plug.dll"); foreach(string file in files) { Assembly assembly = Assembly.LoadFile(file); var types = assembly.GetExportedTypes(); foreach (Type type in types) { if (type.GetInterfaces().Contains(typeof(IController))) { object instance = Activator.CreateInstance(type); controllers.Add(instance as IController); } } } return controllers; } }
And then I was planning on using my list of controllers to register them in the controller factory. But ... how? I feel like I'm on the edge of figuring it out. I guess it all bois down to this question: How do I hook into return base.GetControllerInstance(requestContext, controllerType);
? Or, should I use a different approach altogether?
Creating a Controller Class Follow these steps: Right-click the Controllers folder and select the menu option Add, New Item and select the Class template (see Figure 4). Name the new class PersonController. cs and click the Add button.
Also, MVC relies heavily on reflection, which allows you to inspect types at runtime using strings. Reflection is used in many programming frameworks.
Reference the other assembly from the 'root' ASP.NET MVC project. If the controllers are in another namespace, you'll need to modify the routes in global.asax, like this:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, namespaces: new[] { typeof(HomeController).Namespace } ); }
Notice the additional namespaces
argument to the MapRoute
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With