I have been working with ASP.NET MVC for a couple of months now and I'm still not happy with the layout of my project's solution. I am trying to construct a mid-sized website CMS that is as portable and reusable as possible and there are some obvious problems in the design of it. I am looking for some advice regarding how I should structure my solution in consideration of separation of concerns. I've found a similar question here, but it doesn't really target some of the issues I am facing.
Right now this is how my solution is laid out:
+Project.Controllers - All Controller classes
P+roject.Controllers.Tests
+Project.Core - Utility classes including repetitive tasks and some configuration handlers (this project needs to be better fleshed out)
+Project.Core.Tests
+Project.Models - Model classes, Entity Framework context, and Repository classes
+Project.Models.Tests
+Project.Web - All Views and Content
One major thing I am currently missing is a place to stick my business logic and I feel I've been wrongly placing business logic in my repository classes as well as intermingling it in controller actions. Obviously, I'm very aware of this problem, I'm just not sure where I should placing my business logic in that solution layout. Does my solution structure need to change or can I safely keep that business logic in my Models project? Also, I really don't like that my EF Context is in the Models class, but I don't know of a way to isolate the data layer code from the Entity Classes needed in my model.
How is everyone else laying out their production ASP.NET MVC solutions?
You might want to check out the layout the S#arp architecture project uses or the onion architecture as used in the Code Camp Server MVC reference application. Both projects have had allot of effort put into them by different people to get a good sepperation of concerns in the context of asp.net MVC and domain driven design.
Personally I'm only learning MVC. My experience comes from ASP.NET WebForms but I would go with the layout proposed in the link you gave. The second answer, that is:
Models
Views
Controller
Services
Tests - one for each project.
I would take EF Context and Repositories out of Models and into a data access layer, Project.Data and put your business objects in Project.BusinessLogic (?).
This gives the benefit of putting the two assemblies (Project.Data and Project.BusinessLogic) in other apps you might build on the same domain. That means your next project has a very useful starting point.
Hope that helps,
Dan
Related
Can someone help me understanding Model-View-Controller method to be implemented on WebForms? I am confused on couple of things:
If we have ABC.ASPX and ABC.CS files, what is view? is it only ABC.ASPX file? or combination of .ASPX + .CS file?
do we consider ABC.CS file as controller? If no, will it be a seperate class for controller?
Does database connection and data retreival go into Model or a seperate class which will be called by Model?
Can someone give a simple example for implementing Model-View-Controller in webforms?
Update
Hi guys, my question is how to implement Model-View-Controller methodology using WebForms not about ASP.NET MVC2.0. I apologise for the confusion.
Cheers
I guess I understood what you want to do: you want to implement a MVC architecture above an ASP.NET WebForms application. Fair enough.
All I can say is good luck! Me being there & done that. And how I regretted doing so... :P
Remember: ASP.NET WebForms is a huge abstraction, that tries to make the web into a statefull, event-based, windows-like environment, without any concern of decoupling whatsoever. So, trying to create an stateless, highly-decoupled and non-event-based architecture above that is, sorry to say, near insane.
Please, enlighten yourself and come to the real ASP.NET MVC world... :-)
PS: some people claim of having success implementing a MVP (Model-View-Presenter) architecture above ASP.NET WebForms. Shame on them (but you can try if you really want to)!
As others have posted there is a lot of information out there on MVC, so I'll answer your question...
If we have ABC.ASPX and ABC.CS files,
what is view? is it only ABC.ASPX
file? or combination of .ASPX + .CS
file?
It is both...however the .cs file is referenced as code behind but both make up the view.
do we consider ABC.CS file as
controller? If no, will it be a
seperate class for controller?
No, a separate class would be the controller.
Does database connection and data
retreival go into Model or a seperate
class which will be called by Model?
You could go either way. you could place this logic in the model, however you could also functionalize it out into services, which can then be called as needed by the model. IMHO the second route is the way to go, as I don't want to make my model dependent on external entities and it also makes testing the model easier, as you can separate out the services testing from the model testing.
Diagram can be seen here, which has some great imagery as reference points.
Hi I've been given the task of creating an N-Teir website using the Entity Framework 4 and am coming up against some brick walls, more than likely in my knowledge.
My plan so far was to have these layers
Website (application layer),
What I'm calling Name.Framework (BLL),
Name.Data (DAL),
Name.Entities (contains POCO classes and other struct classes used in website/bll,
Name.Common (utility class)
I've tried to use the repository class, but am struggling to make things work how I thought they would. Below are a few examples of what I'm getting stuck on.
If I want to use .include() would this be in my Repository or is this the responsibilty of the business layer? (and I have no idea how this would work in the BLL)
Same question for .Order()? As I understood it this would need to be in repository or at least passed into the repo in some way?!?
Should I be using the BLL to pass in the Context to the repository/data layer? At the moment when I get an entity from the Data layer any navigation properties that weren't referenced in the repo just come back with 'Object Context Disposed', should the Business layer still hold the context etc so that this wouldn't happen?
Or to summarize this HELP!!!
I need to have this in some sort of order by tomorrow (eek!) as the project leader wants to know if we are going to continue with Entity Framework or move to NHibernate as in-house we have more knowledge of it.
Thanks for any help or suggestions
Matt
Looking for something similar myself I found this. Not looked into it too much at the moment but looks promising.
I'm currently working on a web hobby project with EF4 Code-Only, where I have the following structure ([name] being the name of my project):
[name].Web - An ASP.NET MVC 2 project
[name].Web.Models - Custom view models, along with AutoMapper mappings from my entity objects
[name].Models - My POCO classes, and interfaces for repositories
[name].DataAccess - Some interfaces related to data access, for example IUnitOfWork
[name].DataAccess.EF - All Entity Framework related classes and interfaces
I also have a test project for each of the above, plus a couple of projects with helpers and extensions for the tests.
It might be relevant to mention that part of the purpose of this hobby project is for me to learn how to use EF4 with some design patterns of my own choice (the ones that concern EF in this project are the Repository Pattern and the Unit of Work pattern). Another partial purpose is to build up a code base that I can re-use in later projects, and this has affected the division between projects in my application - for example, if I wasn't concerned with re-use, I'd probably have all data access related classes in one project instead of two.
I've implemented a basic EF, poco, Repository, UnitOfWork architecture largely following this article here:
http://devtalk.dk/CommentView,guid,b5d9cad2-e155-423b-b66f-7ec287c5cb06.aspx
I found it to be very helpful in these endeavors. Don't know if it helps you but others might be interested in the link.
I've been puzzled by what I consider a contradiction in terms: ASP.NET MVC claims to be furthering and supporting the "separation of concern" motto, which I find a great idea.
However, it seems there's no way of separating out controllers, model or views into their own assembly, or separating areas into assemblies.
With the fixed Controller, Model and View folders in your ASP.NET MVC, you're actually creating a huge hodge podge of things. Is that the separation of concerns, really?? Seems like quite the contrary to me.
So what I'm wondering:
how can I create an ASP.NET MVC solution that will either separate out controllers, the model, and the folders full of views, into separate assemblies?
how can I put areas of ASP.NET MVC 2 into separate assemblies?
or how else do you manage a large ASP.NET MVC app - which has several dozen or even over a hundred controllers, lots of model and viewmodel classes, and several hundred views?
I think you're looking for Areas in ASP.Net MVC 2. There are some things to uncomment in the CSProj files, but after that it will copy the views over when you build. I don't think there is any requirement that the Controller or Model classes be in the same assembly as the views.
Walkthrough: Creating an ASP.NET MVC Areas Application Using Multiple Projects
Controllers: AFAIK you shouldn't have to do anything special to throw controllers into their own assembly. At the very most all you'd have to do is override the GetControllerType method of your ControllerFactory.
Models: Zero restrictions on where you put your models. Although this is frowned upon I regularly use persistent objects from an Nhibernate/other ORM layer or WCF/service layer DTO thats are located in a separate assembly as my views. This works the same way using WebForms.
Views: Views in a separate assembly must be marked as embedded resource and then you must use a custom VirtualPathProvider that knows how to get the views from an resource instead of the file system. views from an resource instead of the file system. Again this is the exact same technique you would use for WebForm development.
Regarding mcintyre321 and his Portable Areas answer: The linked project does barely anything custom and simply wraps up the existing MVC 2 extensibility points into an easier to use abstraction. Its barely "custom" and more syntactic sugar.
You manage a large MVC app just like you'd manage any other large app. I dread opening up a 500 page WebForms project because you never quite know whats in each of those code behinds. With MVC distinct functionality is mostly within its right place. Its not contrary at all.
Separating code into separate assemblies is orthogonal to separation of concerns. Where the code lives is not a "concern". Separation of concerns has to do with responsibilities and direction of dependencies of various components. For example, Views are responsible for rendering the output, and the controller knows about the views, but the views don't really have intimate knowledge of the controller.
Likewile, Models don't know anything about either views or controllers, but both views and controllers will know about the model.
However, back to your question. As jfar points out, moving controllers and models into another assembly is trivially easy and will work. Moving views into another assembly is trickier. Embedded resources with a custom virtual path provider is one way, but not one we generally recommend for a high performance site. But if it meets your needs, go for it.
MVC is very extensible and does not require to adhere to the Controller, View, and Model folder structure. You can place the controllers anywhere you would like, however if they are located in another assembly you will need to implement your own controller factory that knows how to locate them. Here is an example for locating your controllers with Windsor.
Your models/view models can be where ever you want. You simply need to reference their namespace in the web.config so views know where to look. (At least I know this is true with the Spark view engine.)
You put your views in any web project. My usual strategy is to create a plain web (non-mvc) project that contains the views folder. (This could even be a legacy web app!) Then all my controllers go in a separate class library. My view models and services go in another.
As far as structuring folders, I usually center my hierarchy around domain concepts. I'd have a folder in each project for Users, Products, Orders, etc. I never have a Models or Controllers folder anywhere.
You need to use portable areas see http://www.lostechies.com/blogs/hex/archive/2009/11/02/asp-net-mvc-portable-areas-part-2.aspx
I am a Java Developer making the transition to the C# world. I've gotten a pretty good handle on ASP.NET MVC (and can compare/contrast it to the concepts I learned for Struts).
However, I'm looking for advice on how to structure my project. Currently, I have two solutions in the project: the MVC Web Application and a ClassLibrary section.
The application uses a tiered architecture: Controllers/Services/DAOs. To make things work "right", I have the Controller and Model classes in the MVC solution, and Services, DAO, and Security in the ClassLibrary solution. Unfortunately, this is causing all sorts of minor issues (example: extending the UserAccount object from the Entity Framework on the ClassLibrary side is ambiguous when I try to extend it on the MVC side for form validation).
The only solution I can come up with is to put EVERYTHING into the MVC project, and organizen what is currently in the ClassLibrary under the App_Code folder. It would solve some issues, but just seems "wrong" to me; my Java projects separated code into a src directory and views (jsp's) into ta webapp directory.
What do some of the more experienced .NET developers think?
Generally in .NET solutions, the best bet is to separate code into different projects only if that code may be useful to other applications, or when the code itself represents a complete solution to some problem domain. A class library that is only referenced by one application project is a waste.
Also, keep in mind that .NET does not allow circular references between objects in two different assemblies (which translates one-to-one with projects usually).
In your example I would suggest that you consider one class library for the model, services, and security... depending on what you mean when you say "services" though.
In most cases, data access is somewhat coupled to the concept of the MVC model, so you might consider putting the data access in there too... but if you have a very cleanly separated data access layer it might fit into it's own class library.
The controllers and views generally should go into the web project directly.
In general, my advice is to split stuff into separate projects ONLY when you have an actual "need" to do so. But assemblies and projects are NOT a good way to represent layers or tiers in most applications. Those are logical concepts that don't always map well to a physical project structure.
If you design your actual classes well and avoid tight coupling, you can usually move code into class libraries later if a real compelling need does arise.
What do you mean by making things work "right"? I find that most issues can be fixed by simply including the namespace in the web.config's namespace import section. When you do that, your models from the other assembly are automatically resolved and they show up in the MVC dialogs, and in intellisense when coding views.
I've been reading a few things about ASP.NET MVC, SOLID and so on, and I am trying to figure out a simple "recipe" for small-to-medium ASP.NET MVC apps that would put these concepts together; the issue that I am most concerned with is ending up with controllers that are too complex and being like code-behind files in webforms, with all type of business logic into them.
I am considering the following architecture, for a small data-driven app:
Controllers: only handle requests, call an appropriate service and return the action result to the View;
Models: POCO, handle all the business logic, authorization etc. Depends on repositories, totally ignorant of persistence infrastructure.
Repositories: implement IRepository<T>, use dependency injection and is where my db code will reside; only receives and returns POCO.
I am considering having services between the controllers and the models, but if they will just pass forward method calls I am not sure how useful it would be.
Finally there should have unit tests covering the model code, and unit+integration tests covering the repository code (following the "red-green" practice, if possible)
Thoughts?
Ian Cooper had a good post on exactly this recently:
The Fat Controller
Simple recipe: (view)Presentation Layer using ASP.NET, (controller)Code Behinds or AJAX Services Layer, (model)Application Services layer, Business Model layer, and Persistance/Data Access layer.
Of course you can slice and dice numerous ways to deal with complexities in order to build a clearly readable and understandable application.
For a recent discourse on the subject, which I have found to be very good, check out this newly published book: Microsoft .NET: Architecting Applications for the Enterprise.
These walkthroughs are quite helpful:
MVC Framework and Application Structure
Walkthrough: Creating a Basic MVC Project with Unit Tests in Visual Studio
Also see: aspnet-mvc-structuring-controllers
Rob Conery has the best answer IMO.
Check out his MVC Storefront Application, which comes with complete source code and video tutorials.