Layering an ASP.NET MVC Web Application - asp.net-mvc

When I develop a WinForms or WebForms app, I create a solution and add multiple projects. The BOL project is a class library for business objects, there's a SQL and a DAL project for ADO.NET related stuff, I have a Utilities project which contains classes for stuff like validation and whatnot. Now the presentation layer which I usually call the GUI contains the forms. The forms work directly with the BOL, which connects to the SQL which connects to the DAL, etc...
I'm sure you all know this already so here's where I get confused. In working with MVC, projects I see all contain this type of functionality but are all in one project, just separated into folders. I looked at the Nerd Dinner application and even that is all in the one project. The end result is a single DLL to handle it all. Is this a good idea, or do you guys separate the pieces into different projects? Usually one DLL has to go through another DLL before it can reach the data access DLL type of thing. Maybe I'm just confused on the whole concept.

You can always seperate this logical layers into seperate physical layers (projects). You can create a seperate project for your Entities, one for your Data Access code etc..
Here is the structure i did for one of my receny project
1) UI : The standard MVC Project with UI related stuff. Controllers and Views and Relevant CSS stuff & Scripts.
2) Entities : The class library Project. My Business entities are here. These are just POCO's which represent my domain modal ( I use this for the CodeFirst Database generation).
3) Data Access : The class library Project. I have my Data Access code here. Repositary, Interfaces and my DBContext class as well.
4) Test : My Unit Tests are in this project.
UI Project has a reference to my Entities and My Data Access Project.
Data Access Project has a reference to my Entities because my Repositary method returns objects.
I have few ViewModel classes also inside my UI project ViewModels folder. I use this for some screens where i have to show data from multiple domain objects. I have a mapping/service class which maps the domain object to view model object. If your project is bifg, you may keep this as a serperate project under the same solution.
The solution looks like this. (This is an open source project i am working on)

Related

How can I inject ApplicationDbContext in another assembly?

I am trying to move some ViewComponents from the main web application to a separate class library (ASP.NET Core 1.1) which does NOT have the Entity Framework models or Identity stuff.
However, those view models depend on ApplicationDbContext to access the data (not all of what is available, just specific things). It kind of partially defeats the purpose of reusability (in other projects) if I have to leave the view component in the main web application.
You can move ApplicationDbContext to a separate project.
Let say ApplicationDbContext locates in Data project, and ViewComponents locate in Common project.
Web project references both projects. Common project references Data project.

Separate solution into different projects

I'm currently learning ASP.Net MVC; I'm using Visual Studio Express 2012 with MVC4 (which is the last version) and I'm totally new to this stuff. My goal is to rewrite a huge web application to MVC, so I was told to separate my main solution into 3 projects using the code-first method:
The core (models and controllers I guess)
The UI (views, scripts, and Content)
And the Database (Entity Framework 5.0 will be used)
I'm quite familiar with MVC, but not separating stuff into different projects. Now I'm a bit lost, I don't have a clue on how to do that, which should reference who, where, how, etc.
Your solution could be structured this way:
UI - ASP.NET MVC application project containing the controllers, views, view models, mapping logic between your domain models and view models, scripts, styles, ...
DAL (EF 5.0, EF autogenerated domain models, Data Contexts, ...) everything that is specific to the data retrieval
The UI layer will then reference the DAL layer.
Some people might also opt to externalize the controllers, view models and mapping logic into a third layer which in turn will reference the DAL layer. The UI layer in this case will reference both other layers.
There are tutorials available on here: http://www.asp.net/mvc
It really helped me out to get the basics of MVC, but be aware - sometimes there are parts missing in the video's, but you can find the code which isn't provided easily elsewhere.
Good luck :)
The tutorials are used to show code first.
create an empty solution using the Visual Studio Blank Solution template
add a solution folder (folder name will be your project name)
then right click that folder and select add project then select "class library" (for The c# classes domain logic)
same again right click the folder and select add project then select asp.net mvc3 template
then same way you create the test template as a new project.
For more information you can follow this book http://www.apress.com/9781430234043

Where should I store class files in an ASP.NET MVC project?

I'm just starting to work with MVC and trying to understand the best practices behind designing an application. In the WebForms world, I typically just created a Classes folder where I stored all of my *.cs files. However, because of the way that MVC uses the folder structure to create different namespaces, I'm not sure that's the right thing to do any more. I can't seem to find any guidance from Microsoft on this topic, so I'm hoping someone here can oint me in the right direction.
Is there a right way to organize files in an MVC app? And, more generally, is there an authoritative place to look for this kind of best practice guidance?
Here's a sample folders structure:
Controllers
Models
ViewModels
Mappers
Views
Repositories
Services
Validators
...
Obviously those layers could be split between different assemblies.
You may also take a look at a sample MVC project structure I wrote.
The MVC namespaces don't dictate where your classes should be kept. However, it makes lot of sense if you store them in proper locations as per their category. e.g. if it's a controller class, you will store it in Controllers folder. If it's a ViewModel, you would store it in a ViewModel folder.
Having said that, I believe what you meant by classes were entities that you use for your business logic. If that's the case, you might want to store them in a seperate class library if you application is big enough and you are creating Plain Old CLR Objects (POCOs) by hand. This is the same as you did in the webforms world.
In case it's not a big application or you are using ORM generated entities like those generated by LINQ or Entity Framework, and not explicitly creating them, you might want to include the .DBML (LINQ) or .EDMX (Entity Framework) files in the Model folder. The Entities will then be inside the auto generated designer files in the Model folder.
Hope this helps.
The only special folder in Mvc is the Views folder (and also the Areas folder but that's an advanced topic) where the frameworks locates view files. Your source code files can go into arbitrary locations. However, the structure that Darin listed is a useful convention that helps different developers working on the same project quickly located what they are looking for
You can also start with a new project using the Empty project template (it's not actually empty) and it will create the basic recomended folder structure for you.

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.

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