14

I'm in the planning stage for an employee intranet system to be built with ASP.NET MVC 4. We'd like the site to consist of separate "modules", each of which provides a different feature: messaging, payroll changes, etc. I'd like these modules to be able to be enabled or disabled at compile time. The homepage will display some kind of navigation that will link to each module that is loaded.

That's easy so far, but I don't want the navigation feature to have to know about the modules beforehand. In other words, I want the modules to be dynamically discoverable; I want to be able to write the code for a new module and then have a link added to the navigation bar with no code changes anywhere else in the source. Each module should have some way of registering itself with the navigation bar, and--more importantly--this should be done for each module as it's loaded.

I believe that this precludes using MVC's Areas, since those are designed for the case when the layout of the site is known beforehand. MEF seems like it might be appropriate, although people seem to have had mixed success in combining MEF with MVC. Is MEF actually the way to go here, or is there a better way to accomplish what I need?

bdesham
  • 343
  • 1
  • 2
  • 11
  • Good question, I have a feeling your solution will probably revolve around using reflection. You can still use areas when you create your items, but your method of building the menu will need use reflection to get all of your types (to save you changing code). What about if they all implement the same interface IModule interface. You could then find all inheritants of the interface to get all the modules you need to link to, problem then is how exactly are you going to associate that with a link without **any** additional data? Hmm the plot thickens... – Mathew Thompson Jan 23 '13 at 15:19
  • 1
    Sounds to me like you want to build a CMS, except that instead of doing the CMS administration from within the CMS, you want it to be done at build time. Which leads me to the question, why do you want it to be done at build time? – James P. Wright Jan 23 '13 at 15:49
  • @JamesP.Wright Well, the reason I wanted to do it at build time was just because that seemed like it would be simpler than exposing this functionality through a page on the site. (Plus, the set of modules used will change rarely enough that the added overhead of this kind of dynamic selection isn't necessary.) But really, more important than selecting modules at build time is the ability of the application to *find* the modules in the first place, which is more the thrust of my question. – bdesham Jan 28 '13 at 14:13
  • nopCommerce (http://www.nopcommerce.com/documentation.aspx) is in part a good example of you want. Take a look on how to write a plugin and their approach for DI. – Rui Marques Aug 27 '13 at 13:32
  • For research purposes I was curious what the 'mixed success' was in combining MEF with MVC. Since codeplex is "Living in the archive" nowadays, the link which the OP provided doesn't work anymore. To spare someone else the time: search with ctrl+f for 'MEF2 with MVC4 via Microsoft.Composition' on the discussion-tab on https://archive.codeplex.com/?p=mef ;) – Kevin Apr 05 '18 at 14:27

2 Answers2

4

I would first have a centralized class that is used for the app to register compiled modules with a static constructor and a static member List of modules that were in the system. The modules would have a static property indicating if its a menu item or not and what order it should appear in the menu.

Each module would have its own static constructor that would note itself in the centralized class that keeps track of modules.

Think of this system more like a time clock system where employees come in and clock in. Then at payroll time, we know to pay all the employees based on who clocked in, etc.

Reflection could also be used if you have an interface contract on the modules they must inherit from that ties meta property info to it.

I worked for Warner Brothers Music and did an internal music processing system for different encoding formats. I made a generic plugin model for encoding with reflection that used inheritance so it could be typecast with reflection to get the basic meta properties of the class. I have not tried using a static centralized class though. Just kind of thought of that randomly as another way to try for fun.

I would also add that I've used MVC serving multiple clients with a baseline of requirement but with also enhanced features similar to what you are trying to do. Instead I converted the MVC into using App_Code rather than requiring a compile. Its easier to push files out this way without needing a centralized compilation.

You can leverage JIT with simple FTP or GIT push rather than needing to compile locally and push DLLs around.

Here is a link to that article on stack overflow

King Friday
  • 688
  • 4
  • 12
  • That sounds similar to what I was imagining. The only issue is, how do I get the modules loaded in the first place? By what mechanism do I tell each of them to register themselves with the central class? This is where MEF seemed like it might be appropriate. – bdesham Jan 28 '13 at 14:19
  • MEF is better. I was giving ideas without looking into it but I would have used MEF given that option if it was out when I did those projects. Seems like a good idea. I don't see why you can't combine MEF and MVC. – King Friday Jan 29 '13 at 15:48
1

You may want to look at using MEF with MVC. This would give you the ability to Add - Take Away as needed without recompiling or deploying. As usual, Scott is a good place to start: http://www.hanselman.com/blog/ExtendingNerdDinnerAddingMEFAndPluginsToASPNETMVC.aspx