I am trying to get my hands on MVC. I am from ASP.Net background.
After creating new mvc 3 application, i got Controller, Models and views under the same webapp project. In ASP.Net, we generally create separate projects for Models and Controllers (which i assume are same as Business Layer). Also i created a separate project for DAL where i will be using EF.
I am confused as is this the ideal solution structure? Should we not create separate projects for each layer? Since i created DAL as a separate project, i had to put a reference of WebApp in it because i wanted to return Model from the DAL and because of that now i am not able to add a reference of DAL to my WebApp.
Can someone please throw some light on what am i missing here? Am i not doing it right?
MVC really leaves the "M" part up to the developer.
Even in their official examples you'll see variations. Your question exposes one of the most common misconceptions about MVC. You should NOT bind your domain or data models directly to views, nor should your controller methods accept them as parameters. See this post on over and under-posting.
Ideally, your controllers will call out to a DAL, and some mechanism will map those Data or Domain models to View models. It is those View models - models that exist specifically to facilitate the UI - that should exist in the WebApp "Models" folder.
So, you were definitely on the right track creating a new assembly to contain your DAL. One of the "easiest" mechanisms for mapping to a ViewModel is a simple method on each ViewModel:
public class MyWidgetFormModel()
{
public string Name { get; set; }
public string Price { get; set; }
public MapFromDAL(DAL.Widget widget)
{
this.Name = widget.Name;
this.Price = widget.Price;
}
}
Update: based on your comments, here is an excellent answer about one user's project layout.
When I started with MVC i followed the Jeffrey Palermo onion architecture. You can read about it :
here : http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
here : http://jeffreypalermo.com/blog/the-onion-architecture-part-2/
and here : http://jeffreypalermo.com/blog/the-onion-architecture-part-3/
It's using a IoC support for decoupling services. I think that you should consider usage of IoC containers because the MVC architecture was thought around patterns using IoC in order to decouple services (layers).
You can also dowload a working sample from http://codecampserver.codeplex.com/ using onion architecture.
It's not the only architecture you can use with MVC but it's a very good place to start and to learn about IoC and decoupling in MVC applications.
Related
I am trying my hands on creating an ASP.NET MVC 5 app without entity framework.
I have some existing database, but do not want to use Entity Framework for that. Came up with simple and uncluttered architecture having Entities, Repository and DAL.
I have created a controller passing Repository context to it.
public class EmployeeController : Controller
{
private readonly IEmployeeRespository repository;
public EmployeeController(IEmployeeRespository _repository)
{
repository = _repository;
}
// GET: Employee
public ActionResult Index()
{
IEnumerable<Employee> Employees = repository.GetEmployees();
return View(Employees);
}
}
Issue here is, I have not created a parameterless contructor for this controller. Now how do I pass my repository context to this controller. I am missing out some step, but not able to figure out.
Also, if anyone know of any downloadable sample application for such scenario, it will be of great help.
Dependency injection is your answer. there are some libraries that will do it for you. You can also do poor-mans injection yourself, or with a service locator.
You can use autofac or ninject that will orchestrate your dependency resolution.
This would help: How do I properly register AutoFac in a basic MVC5.1 website?
I looked at using a Repository design pattern to use with an MVC 5 Application I have been working on, but unfortunately it looked like a major rework of my MVC application, basically I would have to start from scratch again with this application. I found it would be far easier to maintain the MVC application by leaving Entity Framework models intact, even though that slows down the MVC application, my resolution is to have the MVC application run in a virtualized server with more computing resources added to speed up the application. more resources from its current level.
Entity Framework Models are far easier to maintain than using a Repository design pattern, if the application is slow because the EF models have many sub-models as virtual properties, that is ok, the easy solution to the problem is to have a more powerful server running the application, more RAM, faster CPU's, more computing resources, etc.
From my point of view, using a Repository adds far more layers of complexity to an application and makes it more difficult to maintain.
I am having trouble connecting the dots from many posts I have read (and coming to realize I probably need to buy Eric Evans book instead of relying on loads of internet material) I am trying to adhere to domain driven design, but I am having trouble on the best method to communication from the presentation layer to my domain before saving my data back to the database. To keep it simple, right now I have a user class that can have a list of jobs. When a user opens the application their active directory information is queried and this class is populated with their data as long as they have the app open. Then, the user can edit an existing job if they own it or create a new one. I started creating a service class that uses my UnitOfWork class thinking this would act as my communication, but that is where I am stuck.
Current Setup:
DAL - EF 6 generated POCOs and DbContext, Repository, Unit of Work
Domain - Entities, Repository & Unit of Work interface, domain interface services I refer to in this post?
Presentation - MVC (intranet), concrete service?
Questions:
Is the service class the best class to implement for this type of communication (and for creating new instances of my domain classes (e.g. a method to create a new job)? I realize I could use a factory pattern, but I did not want to get too complicated yet)? Would the service reside in the domain layer or do I create a separate project for an application layer? Then would the interface go in the domain layer and the concrete implementation go into the application layer? I feel like that could be over complicating the app. Also, is the service WCF or can I just create my own classes?
How do I map the ViewModel in my MVC layer back to the domain using this service (if that is the best way) without the presentation layer leaking in to the service? I've read up on DTOs, but then is that overkill in the service layer? Or is it okay to expose my domain entities as the ViewModel? I must be thinking about this incorrectly. I cannot picture how this interaction would look in a controller without some leakage. Sorry for all the questions, and thanks.
public class User
{
public int Id{ get; set; }
public string WindowsId{ get; private set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get { return FirstName + " " + LastName; } }
public string Email { get; set; }
public string WorkPhone { get; set; }
public List<Job> Jobs { get; private set; }
public void AddJob(Job job)
{
if(job == null)
throw new Exception("Job is null");
var newJob = new Job(this) //tell the job that this user is creating the job
{
Description = job.Description,
DueDate = job.DueDate,
Name = job.Name,
Reason = job.Reason
};
Jobs.Add(newJob);
}
}
UPDATE: My Solution
I ended up taking a little bit from everybody's answers.
#granadaCoder - I used my EF POCOs as the classes to pass around as DTOs because most of the time that is the data I was displaying to the user in my ViewModel. So it allowed me to use the DTOs as the ViewModels
#ChrisPratt - you are correct. Doing this prevented a lot of extra work. All I did was create a service that had all the queries I needed. And if I ever had to change the EF it would still not bother my other layers. All I would have to do is create the repository and UOW
#MilivojMilani - I did have repeating logic in the controller so the service layer kept me aligned with the DRY principal
#Yorro - I used your points and references to reinforce the design since I was still unsure about the service layer setup. Since this is a smaller project, I setup another folder with my service and interface that I created, no WCF
Stay away from the Repository/Unit of Work pattern if you're using Entity Framework. EF is itself an implementation of this pattern. If you want to abstract Entity Framework, then implement a service pattern that returns fully-baked data exactly how you need it. It's best illustrated with an example:
With EF/Repository
IQueryable<Post> posts = db.Posts.Where(m => m.BlogId == blog.Id && m.Status == PostStatuses.Published && m.PublishDate <= DateTime.Now).OrderBy(m => m.PublishDate);
With Service
List<Post> posts = service.GetPublishedPostsForBlog(blog);
The two key differences here are:
You're returning data already pulled from the database with the service; a repository/EF will return a queryable that may or may not have been executed against the database yet.
All your logic goes into the service method with a service. Whereas, with a repository/EF you build your query in place.
That said, don't get so hung up on the layers of your application. It's not about how many layers you have and what you call them, but rather about abstracting logic away from pieces of your application that shouldn't need to know how to construct that logic. A controller action to return a list of published blog posts, for example, shouldn't need to know what qualifies a post as being "published". That's domain logic that should go somewhere else (like the service method that returns this dataset). The idea is simply to follow the single-responsibility principle: a class/method/etc. should do one thing and do it well. Your controller action should only concern itself with returning the view (and doing the bare minimal amount of work to fetch what that view needs).
As far as mapping goes, the term explains exactly what you do, so I'm not sure of the confusion here. If you want to map Post to PostViewModel for example:
var model = new PostViewModel
{
Title = post.Title,
Content = post.Content,
...
}
Or with a list of objects, you can employ LINQ:
var model = posts.Select(m => new PostViewModel
{
Title = m.Title,
Content = m.Content,
...
}
If you question is simply: how do I do this easier? Then, you can look into a third-party mapping library like AutoMapper.
The Service Layer
The service layer serves as the application's boundery, it encapsulates your domain entities, in other words, it protects your domain. All communication to the domain must go through the service layer. But the Domain Model (at its purest form) should not have any reference to the Service Layer or any other infrastructure layers (DAL/Presentation).
http://martinfowler.com/eaaCatalog/serviceLayer.html
Would the service reside in the domain layer or do I create a separate project for an application layer? Then would the interface go in the domain layer and the concrete implementation go into the application layer?
If you are already segregating your layers into their own projects, then the service layer should have its own project.
Is the service WCF or can I just create my own classes?
The simplest service is just a class, see an example of a service layer straight from Microsoft Tutorials:
http://www.asp.net/mvc/tutorials/older-versions/models-(data)/validating-with-a-service-layer-cs
Here is another example on how to refactor an MVC using a service layer
http://www.arrangeactassert.com/asp-net-mvc-controller-best-practices-%E2%80%93-skinny-controllers/
How do I map the ViewModel in my MVC layer back to the domain using this service (if that is the best way) without the presentation layer leaking in to the service? I've read up on DTOs, but then is that overkill in the service layer? Or is it okay to expose my domain entities as the ViewModel? I must be thinking about this incorrectly. I cannot picture how this interaction would look in a controller without some leakage.
This question is another topic altogether. DTO is a good way for the service layer to communicate with outside layers.
Your questions are very good, and in fact it is the most frequently asked.
Is it overkill to use DTO in the Service Layer?
Is it okay to expose the guts(domain) of my application to outside layers?
How would the service layer interact with outside layers without leakages?
Where should the DTO reside?
I've answered the same questions here: https://stackoverflow.com/a/21569720/1027250
This image provides overhead view on how a service layer fits into a multi-layer architecture. Note that this is not absolute or perfect for every project, you should approach a pattern depending on the need of the project. Additional layers adds complexity, it is a long term investment on a long term project with a large team.
1.If you're using MVC you may or may not have a service layer. Ask yourself a following question - do you use this functionality on more than one place? If the answer is yes - use the application service (not domain service). If no, put it in the MVC controller itself.
Don't put any hydration logic in the domain layer. Domain layer in DDD shouldn't know anything about persistence. Controller/Application service should fetch the data using repository interfaces and save the data using same interfaces. In your case, you should be fetching and saving only the User class, while Job should be below it as aggregate root child. Using UnitOfWork and Repository is perfectly fine. Here is a good article on it =>
http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
2.It is perfectly normal to, in some cases, use domain object as ViewModel class. In other more complex cases, you will have to map properties manually. Mapping is usually best done as extension method on ViewModel class. Some use AutoMapper though I'm against using it when mapping presentation classes to domain. All this mapping work should NOT be done in domain layer. You might have a lot of viewmodel classes and it would bloat the domain layer with presentation layer logic.
Hope it helped.
We've got a solution with multiple MVC web projects and now adding a client-facing WebApi project.
The API will be a much more scaled-down version of what is available through any of the web projects (though it will likely expand much more over time), so we've come to a decision-making point for how to handle the Models.
What are the best practices for handling Models across different projects?
It's my understanding that a Model in a WebApi project will, for example, use certain property attributes which are meaningless to an MVC web application. And also as an example, the Display attribute is meaningless to the WebApi, but very useful in a View.
This leads me to believe I should be creating a separate set of Models for the WebApi, but also wondering if I'm missing something.
I understand that this could be a question that may lead to a range of opinions, so I'm mostly looking for what are considered industry best practices.
In my solution where i have Web API and MVC web app, I have the below structure
Models : My Entity/Business objects. These are created by Entity framework from my database. These are almost same as my db structure. My Repositary methods (for data access) returns either a single instance /collection of instances of this classes. My data access project is a separate class library which has been referred in other places like my web api project etc..
Web API ViewModels : The Viewmodels (POCO class) specific to the Web API interfaces/action methods.
MVC Web app ViewModels : The Viewmodels (POCO class) specific to my razor views. I had even inherited few of these from the Web API Viewmodels and added additional properties as needed.
I use a separate project for the DTOs, so that the projects that need to consume them do not get into issues with circular references.
I would have the WebApi project map your models into the DTOs. If your MVC project is consuming the WebAPI output, it just needs a reference to the DTO project. This keeps you from having to refer to the WebAPI project directly.
I am working on a medium sized MVC project.
The View Models have all been pulled out the web assembly to a separate library. One of the data structures is represented by a listbox and has a MultiSelectList property.
The external VM project does not currently have a reference to the System.Web.Mvc assembly.
Should I add the reference?
Should I refactor the code to not have a reference to the MultiSelectList class? If this is the case where does the RawOptionValues property get converted to a MultiSelectList?
public class SelectListPrompt{
public IDictionary<string, string> RawOptionValues { get; set; }
public MultiSelectList OptionValues
{
get
{
return new MultiSelectList(RawOptionValues.ToList(), "Key", "Value");
}
}
}
I see no benefit whatsoever of putting your view models in a separate project. View models must be tightly coupled to your views, so all you are doing is adding complexity for no appreciable benefit.
I feel the same about people that put their controllers in a separate project. I really don't see the benefit. It doesn't have any structural or design benefits and just makes things more complex.
Of course, the exception is portable areas, but then you're placing everything in the separate project, not just the views or the controllers.
View models are tightly coupled to your views. This is their purpose. So, yes, they should absolutely know about System.Web.Mvc. You have put them in a separate class library - great, but while this might not be necessary, if you decide to go that way, this library should know about classes like SelectListItem, MultiSelectList, ... So go ahead and add reference. Don't refactor your view models - they should work with those classes.
What you should be careful about is not to couple your domain models with ASP.NET MVC.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I'm trying to learn MVC with ASP.Net and am reading Steve Sanderson's book. One thing I'm confused about is where to place the business logic?
For example, when deleting a product all Sanderson has is a method in his CartController that calls the Delete method on the productsRepository. This is strange to me because if there were any business logic, such as ensuring that the product isn't in anyone's shopping cart first, etc. it would have to either be in the products repository or the CartController.
Both of these seem like bad places to put business logic; the products repository is meant to be easily replaced with another (switching from using a db to using a session) and using the Controller means you are putting the business logic in the UI layer.
Shouldn't he be using a class that contains the business logic and calls the repository's delete method instead? The repository being a member variable of the business logic class'?
I typically structure my MVC solutions in a way resembling the following:
X.Core
general extension methods, logging, and other non-web infrastructure code
X.Domain
domain entities and repositories
X.Domain.Services
domain services for orchestrating complex domain operations, such as adding a product to a shopping cart
X.Application.Core
application logic (initialization (route registration, IoC configuration, etc.), web-specific extensions, MVC filters, controller base classes, view engines, etc.)
X.Application.Models
view model classes
X.Application.Services
service classes that can return ViewModels by accessing repositories or domain services, as well as the other way around for updates
X.Application.Web
controllers, views and static resources
Some of these could be combined, but having them separate makes it easier to locate stuff and to ensure your layer boundaries are respected.
A typical controller action for showing the product cart might look like this:
public virtual ActionResult ProductCart()
{
var applicationService = <obtain or create appropriate service instance>
var userID = <obtain user ID or similar from session state>
var viewModel = applicationService.GetProductCartModel( userID );
return View( "Cart", viewModel );
}
A typical controller action for adding a product to the shopping cart might thus look something like this:
public virtual ActionResult AddProductToCart( int productID )
{
var domainService = <obtain or create appropriate service instance>
var userID = <obtain user ID or similar from session state>
var response = domainService.AddProductToCart( userID, productID );
return Json( new { Success = response.Success, Message = response.Message } );
}
I also read Sanderson's first version of his book and it was fantastic - a very easy way to pick up and start using ASP.NET MVC. Unfortunately, you can't jump straight from the concepts in his book to writing a large maintainable application. One of the biggest hurdles is figuring out where to put your business logic and other concerns that lie between the UI and persistent storage (a concept called Separation of Concerns or SOC).
If you are interested, consider reading up on Domain Driven Design. I won't suggest that I know it perfectly, but serves as a good transition from Sanderson's sample applications into something that successfully separates UI concerns, business logic, and storage concerns.
My solution has a separate service layer. The controllers communicate with the service layer (using Dependency Injection - Ninject). The service layer has access to my domain objects / business logic and my repositories (NHibernate - also spun up with Ninject). I have very little logic in my views or controllers - the controllers serve a purpose of coordinator and I strive to keep my controller actions as thin as possible.
My domain layer (entities, business logic, etc.) has no dependencies. It does not have references to my Web project or to my Repository project. It is what is often referred to as POCO or Plain Old C#/CLR Objects.
EDIT: I noticed in one of your comments you are using EF. EF does not support POCO without using something called Code First (was in Community Technology Preview status when I checked last August). Just FYI.
The reality is that there's no silver bullet to this answer, and it really is a contextual question at heart. I like to separate things as much as possible, and business logic is, if you think about it, just another layer in an app.
I worked up a BDD-inspired decisioning engine and released it as an OSS project available via NuGet. The project is called NDecision, and you can read about it on the NDecision project home page.
NDecision makes decision-tree business logic quite simple to implement, and if you're a fan of Gherkin syntax and Fluent coding practices you'll feel right at home using it. The code snapshot below is from the project site, and demonstrates how business logic could be implemented.
This might not be a solution for you, but the idea is, if you already have your domain model in one assembly - a great idea and common practice as suggested in another answer earlier, there's no reason why you can't have another assembly with your "decision tree." NDecision was written with that in mind, to separate the logic into one independent layer.
Hopefully that'll be of some assistance.
If you want scalability, it's bad practice to use data access objects directly from the GUI. So in the example you mentioned, I think you should replace the repository that directly reads or writes to the DB by some business logic class that supports business operations.
I'm trying to learn MVC with ASP.Net
and am reading Steve Sanderson's book.
One thing I'm confused about is where
to place the business logic?
In the model (M in MVC), or domain layer. These are a separate set of types (preferably in a separate project) that represent domain models, services and repositories.