I'm surprised I can't find more discussions out there about an issue that is really bothering me on our project using ASP.NET MVC.
How can you deal with a Visual Studio solution that has multiple projects? The MVC framework has the Models/Views/Controllers folder in the main project. But what if you want to break up your solution into multiple projects along logical groupings and bring the models/views/controllers along with it? When I think ahead to the end of the project, there will be many classes in each of these folders. It doesn’t paint a cleanly organized structure that will aid maintenance. We’d like a way to either move the classes to the projects that they relate to or at least use a folder structure to aid in the organization.
I assume that one option would be to use the same namespace in all of the other projects as is used by the main project, but I’m not a huge fan of that approach b/c this is not the approach that we’ve normally taken when defining our namespace.
I suppose we could at least create sub folders inside of the M/V/C folders and not carry forward the folder names to the namespaces. I’m assuming then that the classes could be found?
Some background on our project: It is a public facing web site that has many business transactions that the user can perform (about 50-60). Each transaction has a series of web pages that the user navigates through, in order to accomplish the different services provided by the site. We are using a single controller for each transaction (there have been long discussions on whether we should have a controller defined for each transaction or if we should use a higher level grouping and therefore reduce the number of controllers, but some information that we've encountered on the web (http://codebetter.com/blogs/ian_cooper/archive/2008/12/03/the-fat-controller.aspx) brought us to this decision.)
What are some recommendations? Have others solved this issue in a way that they are happy with?
Thanks
Jon.
Have a look at Areas.
Areas is a concept borrowed from MonoRail, which organizes controllers into logical folders.
http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx
Areas are supported in Asp.Net MVC2.
Scott Gu has a blog talking about the Area Support here.
From his post.
Each area can be implemented as a
separate ASP.NET MVC project which can
then be referenced by the main
application. This helps manage the
complexity when building a large
application and facilitates multiple
teams working together on a single
application together
I always delete the "models" folder and reference separate class libraries that represent my business logic layers and data access layers. I also have some solutions where my controllers are kept in separate projects from my views. I agree that in larger applications, the single project model is inappropriate. Even in smaller apps, especially where model code must be shared with other applications, putting model classes in the actual MVC project is a bad idea.
Related
I have a solution which contains 2 MVC Website Applications (Website & Website Admin System). As I am progressing with the build there is a lot of common code especially in my View Models, HtmlHelpers etc. Is it good practice in MVC to treat these two sites as separate entities and keep code in one site specific to that site and manually copy code across to second site? Or is there a practice to share this common code across web apps?
It is just natural for me to refactor common code when I see it? However I am not so sure how this works within an MVC environment. Any suggestions or comments welcome.
You can create a class library project and push that code to that project. Then have both website projects reference that DLL. I believe views are about the only thing in MVC that you can't do that with. I believe you can do it with controllers too, but I haven't tried it.
If your sites are sharing many ViewModels and HtmlHelpers I'd take a step back and examine why they are two separate sites. Is the second one an Admin area of the first site, or is it a completely separate entity altogether? If the first, I'd probably have everything in one site. If the second, I'd do as Brian Ball suggested and create a library project that the two sites share.
I'm designing a Module that is to be consumed by two distinct WebSites. Everything will be written in MVC (the module and both web applications).
I would like to design my module so that the code can be included from a shared location. I only want to maintain a single version. My first thought was the Area feature of MVC 2. But from my reading it appears as though MVC 2 only "officially" supports Inline Areas.
It sounds like MultiProject support for Areas could be dropped in the near future. What are the pros and cons of Areas implemented as single projects vs multiple projects in asp.net mvc
Are there any alternatives?
A real world example of my design would be creating an MVC Shopping Cart (this would be the shared Module) and consuming it on two different MVC web sites (say a Book Store and a Bicycle Parts Store).
MVC Contrib's Portable Areas are just what you need:
http://www.lostechies.com/blogs/hex/archive/2009/11/01/asp-net-mvc-portable-areas-via-mvccontrib.aspx
My experience has been nothing but positive. Have 3 apps sharing 3 portable areas. One is going into production pretty soon.
You can still make it an Area, maintain it in one place and copy it to other projects when needed. There's no way I know to make it work out of the box without setting up the appropriate routes in the consuming web project.
Other than that, I would be interested in a solution too.
we are building a new web application using Microsoft ASP.NET MVC2 and Entity Framework 4. Although I am sure there is not one right answer to my question, we are struggling to agree a VS2010 solution structure.
The application will use SQL Server 2008 with a possible future Azure cloud version. We are using EF4 with T4 POCOs (model-first) and accessing a number of third-party web-services. We will also be connecting to a number of external messaging systems. UI is based on standard ASP.NET (MVC) with jQuery. In future we may deliver a Silverlight/WPF version - as well as mobile.
So put simply, we start with a VS2010 blank solution - then what? I have suggested 4 folders Data (the EF edmx file etc), Domain (entities, repositories), Services (web-services access), Presentation (web ui etc). However under Presentation, creating the ASP.NET MVC2 project obviously creates it's own Models folder etc and it just doesn't seem to fit too well in this proposed structure. I'm also missing a business layer (or does this sit in the domain?).
Again I am sure there is no one right way to do it, but I'd really appreciate your views on this.
Thanks
Jfar is correct. It doesn't matter at this point what structure your solution takes. You'll have plenty of time to rearrange the solution later. I've done many small MVC applications and one large one and I'm still evolving how I prefer to structure the projects/solutions.
As far as structuring and MVC project, the only folder that really matters is Views. I have started to break away from the /Controllers and /ViewModels folder structure and grouping things by domain concept. If Student is one of your domain concepts, I'd have a Students folder in the domain project, in the MVC Views folder, in the services project, etc. All the domain classes, view models, controllers, etc would go under the same folder name (in different projects). That way you always know directly where to go to if you want to modify Student related code.
Also, we have a Web project that hosts the views and a separate class library project that contains the controllers. Most of my solutions have 12-30 projects.
I believe you are right to consider the project structure (and namespaces) at this early stage. Although jfar's point is well made how often are you given the luxury to restructure your projects and namespaces before your first release? Even something as you suggest is better than throwing everything into the same project - surely?
Wanted to add - it's not so important how You organize Your folders/solution, it is important how You organize Your code.
So - If Your app won't be properly layered using fancy techniques like dependency inversion, won't be neat and testable - it won't matter if You put stinky code in one or hundred folders. You won't be able to migrate from sql to Azure, from mvc to silverlight.
What makes sense to you and your team?
What folder the code is in means nothing ( besides minor namespace generation ) and can be easily changed by dragging and dropping.
Right now organization barely matters, you have so little files its easy to browse around the slution. Once your 6 months in and you have 1000s of files thats when you'll need to start thinking about organisation.
With my own personal projects I dump everything into a single project, at work I have a 17 project solution and 50 folders. Code is code.
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.
We will be developing a very large vertical market web application, and are leaning toward the MVC approach.
It will have 1 Master Page common to all views in the application.
The master will provide a navigation/search framework for the entire application
that will allow users to search and select entities and then navigate to a function to perform.
The database model will have 700 to 1000 tables.
The application will have hundreds of controllers.
Controllers and their views could be grouped together into one of the many (20-50) subsystems in the application.
(We are looking at an areas approach to aide in organization).
We want to be able to deliver enhancements/updates in small functional pieces.
These might me a new function, a bug fix, customer dependent functionality, or optional modules separately purchased by the enduser.
We spent too many years developing/supporting and delivering one large windows vb app exe.
We would like to take another approach.
Management does not want to deliver one large application. They want to be able to deliver
small incremental pieces when necessary.
We may want to create a deliverable that contains one controller, and only a couple views, and a portion of the model.
To deliver it, we want to copy a dll to a bin folder, and create a View folder and copy in the new view(s). As simple as possible!
I have spent many days researching this and haven't come up with a clear path to proceed.
(Every tutorial and article I found assumed a single project.)
How do we structure the application to accomplish this?
How do we break up the application into separate projects/assemblies to do this?
Can you build a base project that contains the Master Page, authentication, and Global routing,
and then reference this in each of the potentially hundreds of other projects for each of the modules?
In development, does each sub-project need to contain the entire base project, or just the shared views folder, Global routing,
and web.config and a reference to the base project dll?
Any detail documents explaining this approach?
Any development/Testing issues?
Thanks for all input, we have to get this going soon.
Update:
Followed the example here link text
It is a great starting point!
I think this is exactly the case where DLR would help. Your Controllers and Views can be stored as scripts in the database. It will be very easy to deliver your application as a set of "small functional pieces". You could start from reading Haacked - Scripting ASP.NET MVC Views Stored In The Database
Absolutely, break the project up into sub-projects / modules containing your controllers. You can use an IoC container like Unity, Spring.Net, or Castle Windsor to locate your appropriate controllers in the child projects.
Implement your own IControllerFactory to do the Controller lookups in the IoC container based on the controller name passed to it. You're looking to put in place an IControllerFactory.CreateController method that looks something like:
public IController CreateController(RequestContext requestContext, string controllerName)
{
return (IController)IoCContainer.GetObjectByName(controllerName);
}
Then you should be able to simply modify your IoC configuration file to define your new controllers as they are deployed.
Google for MVC with MEF. There is an example by one of the MEF team that will suit your needs exactly.