ASP.net MVC and modularity - asp.net-mvc

I'm trying to find out if there is a way to use ASP.Net MVC to design a modular web application.
By modular, I mean that I should be able to drop a "package" (which could be made of a bunch of files, I don't necessarily require a single file deployment).
The idea is to deploy additional functionality seamlessly. Functionality could go from tweaking the existing web site (that is the easy part, any plugin architecture would do), up to having whole new site areas.
I'm looking for pointers as to
- if that is even possible
- what choices I have to make w/ regards to view engines for example
- any gotchas I should be aware of
I found one or two references, but ASP.Net MVC moves fast and they might be out of sync.
Any input is welcome (up to and including "don't go there") !

It's easy.
Start with creating a class library with the same structure as a regular MVC project. Make sure that all views are changed to "Embedded" in file properties.
Use an inversion of control container like Autofac and just tell it to register all controllers in all assemblies found in the current directory.
You need to create a custom VirtualPathProvider that looks for your views in all found plugin dlls. You might also want to make the VirtualPathProvider modify the views so that #inherits YouBaseView<TModelName> is added, since Views\Web.Config isn't used for embedded views.

I am thinking about doing something similar, I found this to be a good article to get started: http://sankarsan.wordpress.com/2009/04/12/a-layered-aspnet-mvc-application-part-iv/
What I have done so far is opt for the Castle Windsor IoC container - information about ASP .NET MVC and Windsor is here: http://stw.castleproject.org/Windsor.Windsor-tutorial-ASP-NET-MVC-3-application-To-be-Seen.ashx
I then use the Razor Generator from here: http://razorgenerator.codeplex.com/ so that I can compile views into separate assemblies.
And some code from here: https://github.com/csteeg/BoC/blob/master/Src/Commons.Web.PrecompiledViews to build a view engine that uses the IoC container.
With those two things and a few interfaces that are custom to my application I have been able to drop in "modules" by putting DLLs into a folder and have them appear as tabs within the hosting application.

Related

Pack my ASP.NET MVC pager into NuGet package?

I've a pager functionality I use in some of my ASP.NET MVC projects. It consists of a couple of classes and interfaces (to generalize approach to paging of different datasources) and .aspx or .chtml view.
I can put my C# code into NuGet package/library assembly but what to do with view files which can be different for different projects (different pager design, for example)? One approach is to put HTML to HTML helper, written in C#, but I don't like putting bit chunks of html into C# code.
Is it possible to put views to NuGet package or should I use recipe feature?
I've wanted to push the usage of Nuget in MVC apps to reuse MVC apps themselves not just code - views too. I did manage to pack it up but it has like dozens issues and the experience is horrible.
If you have a pager functionality built inside an ASP.NET MVC Web application project then you can just pack it up and it will pick up the Views too. It does become a lot trickier when using DI, when using Areas, when using localization (resource files don't get picked up). For instance, Area routes might get compiled and included, on the other hand the main global.asax.cs will never be included in the package (so you have to manually copy the routes over if you have them in there).
But it does include stylesheets, so you can style your pager to the default stylesheet which you include in your package and that way you have also solved the issue of design modifications.
But all in all NuGet isn't best suited to pack MVC (or classic ASP.NET webforms) apps.

Where do utility methods fit in ASP.NET MVC setup?

Where do utility methods go in MVC setup? They are not Models, Views or Controller. They don't belong in those folders. So do is the only right thing to do is to keep utility methods outside your ASP.NET MVC project and put them into a project of their own?
It really depends on how big your project is. If it's just a small project with a few utility methods, then what I normally do is put them in a folder called "Infrastructure" inside the MVC project.
The initial setup you get for an MVC project is only really a guide (with some exceptions), and you're free to add folders and put code in them if you want to.
If there's going to be a lot of supporting code, then a separate project might be cleaner and easier in the long run.

DAL -> BLL <- GUI + composition root. How to setup DI-bindings?

I have made a three-layer application with refrences going as described in this answer:
DAL with Repositories -> BLL with services and IRepository <- Asp.net mvc-app
To get this running with dependency injection I see a few options:
1. Add a reference to DAL from the web-app to be able to setup bindings on application start.
2. Use a container with xml-configuration
(3. Use reflection to load the dal-assembly and find types)
Option 1. is easy and also makes the DAL.dll be copied to bin but then I suddenly reintroduce the reference I worked so hard to get rid of. The repositories can now be accessed directly. Option 2 and 3 seems unnecessarily complex.
Is there no other way?
Split up the ASP.NET MVC application in two:
One part is your original ASP.NET MVC application, but without any logic whatsover. Just keep the Composition Root and your Views (.aspx, etc.) in this project. Since this is the Composition Root, you can have references to all your other projects. However, since all logic would have been extracted, this is now a Humble Object, so it's okay to have all the references at this level.
Extract all the logic (Controllers, etc.) into an Application Model project, which would just be a normal library project (.dll) that references the ASP.NET MVC binaries. This project would need to reference the BLL to get at the interfaces, but that's okay. However, both the Application Model and the BLL are effectively shielded from the DAL.
The resulting layering would look like this:
ASP.NET MVC application
Application Model
BLL
DAL
Mark Seemann's answer gave me the idea for this variant:
DAL with Repositories -> BLL with services and IRepository <- Asp.net mvc-app
^------------------------^--------- Composition Root <-------ยด
This is meant to illustrate that instead of letting the Web project reference the DAL it references a separate Composition Root-project that references both DAL and BLL. The composition-root-project has a single class with one method that define the bindings. It gives these additional benefits:
Only three layers. Four layers would be a tough sell in the team.
Loose coupling is ensured. It is not possible to access the DAL from view-code.
Better tool support. Controllers remain at the standard location so "Add Controller" is accessible on the context-menu and missing views are highlighted in the controller-code. Also there is no need to configure or write a custom controller factory.
I don't see any big drawbacks.
Just go with Option 1.
Just because you have a reference to the assembly doesn't mean your breaking the SoC.
The Web Project still knows nothing about the underlying implementations, only the interface.
The Web Project is the "aggregator" of the below layers therefore it makes sense it should know about them in order to configure them.
I split the MVC project in two roughly as described in Mark Seemans Answer.
The MVCApplication is a humble object and requires references to everything, but doesn't have any of the MVC code, apart from global.asax (which it needs) and web.config (which it seems to want).
The MvcUI project only references interfaces and uses dependency injection.
If you put both the projects (.csproj files) in the same directory then the Content, Controllers, Models, Scripts and Views folders are all actually in the same place, so all the tooling works.
The picture of the solution below shows the idea.
The directory structure looks something like this
And you end up with a Dependency graph like this
Recently i was following the same thing and figured about the MEF (Managed Extensibility Framework). With the help of MEF and reflection you can get rid of that DAL/Unit of work reference from your composition root and you don't need to have 2 mvc projects as discussed above.

Pluggable ASP.NET MVC framework query

I am trying to create a pluggable ASP.NET MVC framework. I have extensively used Prism (CAB for silverlight) and am a huge fan and wish to implement the following items in my pluggable ASP.NET MVC framework
The framework will have a host to load the unity container and other infrastructure items like logging services and all.
Plugins will be independent MVC2 application. Every application will have IModule interface implemented which will initialize and register Controllers/VIEWS(Is this possible!!!) type in Unity?
This IModule will also register custom routes per plugin and add it to host Routes collection.
When the application will start, the plugins list will be loaded from the database/external file and IModule of the project will be called which will load the above mentioned items in Unity Container.
Whenever any request is made, the controller will be loaded from unity and the Views will be loaded (Is it possible that I register a custom view engine in unity which will point to physical path rather than embedding the resource in the dll)
Is this possible. The question may sound a bit stupid... :)
This is generally possible, though a lot of work from scratch. Fortunately Microsoft's Orchard project already does pretty much everything you are asking, and you can download the MVC source code to see how it's done. See: http://orchard.codeplex.com/

Is there a point to have multiple VS projects for an ASP.NET MVC application?

I'm developing MVC application where I currently have 3 projects in solution.
Core (it is supposed to be for Repositories, Business Classes, Models, HttpModules, HttpFilters, Settings, etc.)
Data access (Data provider, for instance SqlDataProvider for working with SQL Server datastore - implements Repository interfaces, XmlDataProvider - also implements Repository interfaces but for local XML files as datastore)
ASP.NET MVC project (all the typical stuff, UI, controllers, content, scripts, resources and helpers).
I have no Models in my ASP.NET MVC project. I've just run into a problem because of that coz I want to use the new DataAnnotation feature in MVC 2 on my Business class, which are, as said in Core, however I want to be able to localize the error messages. This where my problem starts. I cannot use my Resources from MVC project in Core. The MVC project references Core and it cannot be vice-versa.
My options as I see them are:
1) Move Resources out but this would require correcting a whole bunch of Views and Controllers where I reference them,
2) Make a complete restructure of my app
What are your thoughts on this? Also, Should I just move everything business related into Models folder in MVC project?? Does it even make any sense to have it structured like that, because we can just make subfolders for everything under MVC project? The whole Core library is not intended to ever be used for anything else, so there actually no point of compiling it to a separate DLL.
Suggestions appreciated.
Throw it all into one big .csproj boat and use folders to separate things. Its much easier to navigate folders than separate projects. You won't have to fight namespaces all the time and everything is right were you expect it. You completely eliminate any .sln kung fu when things aren't int he right location or assemblies need to be referenced and you can spend more time coding rather than moving .sln bits around.
Some people say it makes it harder to "swap out an implementation" which is baloney. Swapping the contents of a folder is just as easy as swapping the project.
The MVC source is what made me fond of this approach. They flatten everything out and its really easy to swim around their source code.

Resources