I am trying to understand the concepts of a good designed project.
I am using ASP.NET MVC and i am trying to create a layered (pluggable) project.
The current project structure what i have now is this:
LayeredProject - the MVC Project containing Controllers
LayeredProject.EntityFramework - contains all the POCO classes used for database. (i am using Code First approach)
LayeredProject.Model - this should contain all the business objects used in the project.
Saying that the project is a eCommerce website, i would structure it like this:
In the LayeredProject.EntityFramework project i have classes which corresponds to the database tables. Category, Product, User. This project is used only for saving and loading data from database, and those objects should not be used for other purposes. This project has a reference to LayeredProject.Model project.
In LayeredProject.Model project i store all the objects i work with, which most of them are exactly copies of LayeredProject.EntityFramework POCO's objsects and some other Services Classes used.
In LayeredProject i keep all my ViewModels classes, Controllers, and different UI logic. This project has a reference to LayeredProject.Model project.
First of all, i am not sure that this is the right way of doing this.
And, it this is the right way of doing it, then i get a little confused because i will have a duplicate of my POCO classes in EntityFramework project and also on Model project.
Please help me understanding this
You can Design Your Project using layered structure as well using MVC. The Controller and view part should stay intact. You can divide the business logic part as many layers as you want. The model should come as a result of the number of layers you are expecting. For this keep your business logic in a separate project (not neccessary: it can be there in web project itself), refer the dlls from that project to the MVC web solution. Pass the models which are generated as a result of database querying to the web solution and with the help of controller render the view.(I have done my project using this style)
The MVC project should contain:
view models: models for the views, i.e. models that are very specific to render each view (these model are not the M in MVC). This models usually contain the data which must be shown or edited in the view, as well as aditional necessary information to render the view: for example, if the view must render Drop Down Lists, the view model should contain the corresponding SelectList or IEnumerable to populate the list. You can use mappers, like AutoMapper or ValueInjecter to move data from the business entities (entities coming from the Business Layer) to the view models, and viceversa. Or if appropriate, you can use directly the business entities as properties in the model view (the view model doesn't need to be flat: it can contain objects as properties)
views, strongly typed with the view models
controllers: this controllers use the Business Logic (that is the Model, the M in MVC) to control the application flow, to create and provide the model views for the views, and to react to the user actions
UI helper: I usually add this layer to fulfill the DRY principle. I.e. if I have to prepare a SelectList and it's going to be used in many views, I do it in this layer, and use it from all the necessary places. This can include calculations, orderings, or anything tighly related to the UI, so it doesn't fit in the Business Layer (Model). This uses the Business Layer, and provides data specific for the Views.
Those are the specific and critical parts of MVC, which includes the VC in MVC (views and controllers) The M in MVC (Model) is the business logic which can be done 'as usual'. I.e. you don't have to do anything special in your business layer to use it with MVC. You can use the technology of your choice (a traditional DAL + BLL, WCF, WS, or whatever you want).
This is something which works well for LOB applications. Of course, if you're making a toy application, you can forget this all and make something more monolythic. But I only recommedn this for very little applications with scarce maintenance needs.
These are examples of objects in several layers that allow to edit a "Pet":
Business Logic Layer:
PetService, a class which can be use to read, write, find, and modify pets (as explained above it doesn't matter how this is implemented)
Business Entity: it's the BLL entity for managing Pets. This could be a POCO object or a DDD entity:
Pet - int Id, int PetTypeId, string Name...
View Model: contains a Pet proerty, as well as a list of PetTypes, so that the view can render a drop down list for the PetTypeId:
PetViewModel - Pet ThePet, SelectList PetTypes
UI Helper: if the PetTypes is going to be used in more than one or two views, a PetUiHelper could provide this select list for all the views that require it:
PetUiHelper - GetPetTypesList()
Pet views: a strongly typed view for PetViewModel
Views\Pet\Edit.cshtml
PetController: uses the PetService to create the views, and their model views.
PetController - Edit(int id) --> returns an Edit view, woth its corresponding PetViewModel. There must be also an HttpPost Edit action which receives the user input in an specific model or the PetViewModel, or the Pet plus the Id or whatever. This depends on what you're editing.
Finally, if you know how to use DI, you can use Unity.Mvc or any of the other options to inject the Business Services in the controllers.
seems your using the Code First approach to build a data access, you can dig in this extensive article and gain more insight.
http://ofps.oreilly.com/titles/9781449320317/ch_AdvancedData.html
You probably have one too many layers in there, there should be no reason to separate the model with the business logic from the LayeredProject MVC layer itself unless you are planning to have a client app or some other separate project to access the model. In the MVC project you already have a model folder that can be used for that. However in the MVC project you should also add a "ViewModels" folder to keep models that are specifically used for the view concerns (e.g. DTO objects).
This project shows a nice simple way of keeping the things separate simply within folders in the MVC project: RacoonBlog Project. Although it uses RavenDB rather than EF the ideas are the same.
Most MVC apps I have worked were layered in this way
MVC Project: Had the controllers, views and models. The business logic resides in the model.
The Data Access layer (Persistence layer) : This project uses an ORM. (In your case entity frame work)
Classes that are mapped to the database tables reside in the Model and not the data access layer.
Related
I m new to MVC and will appreciate if you can clarify my question.
What is a model?
Is it just Poco class having fields/ properties, for example a Person class?
Or is a model a data structure having data in it, for example List<Person> or List<Users> ?
Or as per asp.net a working Model is a business layer or service layer, can have business rules, logic, validation and i can talk to other layers?
Thanks for your help and guiding me.
There are ViewModels and DataModels. Poco models are considered the DataModels.
Poco models can also be used as ViewModels but its better to use separate models for views. Because a ViewModel can consist of one or more Poco models.
Here you will find more details: http://rachelappel.com/use-viewmodels-to-manage-data-amp-organize-code-in-asp.net-mvc-applications
One important note "Model" in "ASP.Net MVC" is different than "Model" in classic MVC design pattern, so be careful when looking for definition/resources. "Model in classic MVC" covered in How should a model be structured in MVC?.
"Model" in ASP.Net MVC is object (usually class) that ideally provides all data needed to render particular view.
There is no restrictions on whether such object used for any other purpose. If you view shows one particular item from data access layer (like Person) you can easily share the same object in data access layer and use it as view model.
Note that as of MVC5 views can't call methods asynchronously, so it is good idea to make sure all data is present in the model class instance rather than letting view to call DB/other remote services.
First of all , I use EF into Dal layer (separeted project from MVC, same solution). The generated models from EF's EDMX file are the actual models from Model layer?? If so, how do I access these models to work in MVC's View layer? I think it's wrong accessing data layer directly from view to work with these models, and If I make a Model layer with "my models" and translate Dal's models into mine models... it'll be duplicated code.
Probably I'm getting something wrong, but most of egs. are with code first approach, and I can't figure out this.
You are right in your idea of not accessing access the Models in your DAL directly from your presentation layer.
To avoid duplicating code when translating your DAL objects into the Models used by your views, you could use something like AutoMapper, which is supposed to do the heavylifting for you in exactly that scenario.
I think it's wrong accessing data layer directly from view to work with these models...
That's right, the appropriate method is using View Model
When you have dozens of distinct values to pass to a view, the same flexibility that allows you to
quickly add a new entry, or rename an existing one, becomes your worst enemy .You are left on your
own to track item names and values; you get no help from Microsoft IntelliSense and compilers .
The only proven way to deal with complexity in software is through appropriate design. So defining an object model for each view helps you track what that view really needs. I suggest you define a
view-model class for each view you add to the application.
-- "Programming Microsoft ASP.NET MVC" by Dino Esposito
A ViewModel provides all information that your view requires to make itself. To transfer data from ViewModel and a business entity you can use AutoMapper.
Don't worry about duplication, those are two different concept and should be separated from each other; it makes your application easy to maintain.
I may be mistaking but to me, using generation from EDMX provides you with the DbContext which could be considered as the DAL and entities which could be considered as the Model.
So you might directly manipulate entity instances as your business object. Manipulation of the base through the DbContext should appear in the BLL layer. Additionally, you might implement DTOs where needed.
This, of course, assumes you want to use entity framework code generation. Other options like using POCOs might be more relevant considering your overall architecture.
I use a view model in my local project and the models in the other project. Then put references to the models im gonna use on the page in my view model. Then reference the view model on my page. Let me know if that sounds like something you want to do and I can edit in some code.
I'm new to using the ASP.net MVC framework (and C# too). I have more experience using JSP + JSTL MVC framework. I want to know how to run custom queries if I need to do more complex sql.
In the JSP framework, I'm used to creating DAOs to query sql tables which doesn't seem to be the case in ASP.net. For ASP.net, I noticed that we use LINQ to do the querying over a DBSet object from a model.
My Questions:
Where do I write the custom query code? In the model?
How do I write it? Is it through some sort of db.execute statements?
Are there any configuration changes I need to make?
Examples and other resources would be nice.
I tried looking through the asp.net MVC tutorials on asp.net, but I couldn't find anything.
How you execute SQL queries depends entirely on what data access framework you are using. You can write plain SQL with ADO.NET and execute queries in a manner much like that you would expect.
In answer to the second part of your question, this should be done in a data access layer and be completely unrelated to your ASP.NET MVC application itself. Any necessary logic for instantiating and communicating with classes in that abstracted layer should reside in your controller (and, ideally, be loosely coupled from your application via the use of interfaces and/or service layers).
In this sense, yes, it belongs in the model. However, bear in mind that, conceptually, the 'M' in ASP.NET MVC is the domain model (i.e. the aforementioned data access layer), not the view model. The view model is just an independent wrapper that is designed to store relevant data for a given view and should - in most cases - be completely devoid of logic whatsoever.
In the JSP framework, I'm used to creating DAOs to query sql tables
which doesn't seem to be the case in ASP.net.
It is very much the same, you should have a separate DAL project with your DAO objects and reference those from your Business Layer (another separate project). The ASP.NET MVC project itself will add a reference to the Business Layer project which in turn will add a reference to the DAL. That way, you can keep a 3-tier architecture:
UI (ASP.NET MVC project)
|
|
Business Layer (POCO objects (= to POJO), validation, biz logic) - separate project(s), depending on whether you put your POCO objects in the same project or not.
|
|
Data Access Layer (You can use ADO.NET, EF (LINQ), etc.)
An ASP.NET MVC app usually is composed of 3 folders: Models, Views, Controllers but everything that's typically placed in the Models folder is really your Business Objects so I tend to get rid of that folder completely and I am left with just the Views and the Controllers folders. The views are just the html markup, pretty much. The Controllers classes simply call the methods from the business layer and passes the results to the views. So for example, a UserController class will look something like this:
public class UserController : Controller
{
public ActionResult Index()
{
var allUsers = UserBusLayer.User.GetAll();
return View(allUsers);
}
}
I’m building a project that currently has 3 assemblies:
UI
Core (Services & Models, Utilities)
Repositories (Linq2SQL)
Dependencies are
UI -> Core
Core -> Repositories.
I’d like Services and Models to be in their own assemblies and end up with something that’s built around the Models i.e.:
UI ->Models, Services
Services -> Models, Repositories
Repositories -> Models
Models
The system I’m building is basically a website CMS so I’ll have a model for a web page (PageModel) which has a collection of child web pages. PageModel can call methods in a service (PageService) to populate its child pages but in the new design that can’t happen because the Models assembly necessarily knows nothing of the services assembly.
I’ve considered some of the ideas in the Onion Architecture (namely dependency injection) to solve this, but it seems that a more elegant /obvious solution might be available.
Do I need to introduce another layer of Model? View Models? I think what I’m calling Models are Domain Models... I may very well be wrong! Services would then be Domain Services?
So my solution would be:
UI -> Services, ViewModels, Models
ViewModels -> Services, Models
Services -> Repositories, Models
Repositories -> Models
Models
In this example I imagine my PageViewModel would extend PageModel and use the PageService to fetch it’s child pages..
Any suggestions appreciated. Also any pointers on what these layers of models are usually called? Am I talking about DTO Models rather than Domain Models here? And Domain Models rather than View Models? It seems like what I'm proposing to use the View Models for isn't really the job of a View Model..
Thanks
EDIT:
Something I hadn't mentioned originally is that my Domain Models aren't basic translations of single database entities like you tend to see in most tutorials. A domain model can contain data fields that come from several related database tables.
So would it be worth having a set of Models purely to encapsulate the the data in the Domain - without any methods/properties that fetched related objects or saved the object back to the DB etc? - Data Transfer Objects.
From looking at a couple of scribbled diagrams this would mean having a set of mappers in the domain layer (which seems wrong..) to translate DTO models to Domain Models and back. The project would become built around the DTO models rather than the domain models but given what's encapsulated by the DTOs I don't see that being a problem.
For anyone who's interested, the proposed dependency structure would be like so:
UI -> Services, Domain Models
Services -> Repositories, Domain Models, DTO Models
Domain Models -> Repositories, DTO Models
Mappers -> Domain Models, DTO Models
Repositories -> DTO Models
DTO Models (no dependencies)
It's a bit of a mess! And all just because I want my PageModel to be able to fetch its own child PageModels.. It's looking like having a go at dependency injection might not be such a bad plan.
Thanks to the guys who've replied. You've given me loads to think about.
You can accomplish this just fine with the onion architecture.
I'll have for example:
UI, Domain, Data Access, Services
UI
Services
Data Access
Domain (contains view models as well)
UI can access any one.
Services, only data access and domain.
Data access - only domain.
My repository interfaces are in the domain project, and they are implemented in the data access project.
I also keep other interfaces in the domain project (IContext, IUnitOfWork, etc) so I have one central place and not spreading too many interfaces between projects.
DTOs would be used simply for transferring between layers, if you deem appropriate. There's no reason to me you can't pass a domain model from a data layer on up, some choose to only use DTOs here. I'll do the mapping in the UI layer (ex MVC controller) to a ViewModel since I can make use of AoP to do it for me ([AutoMap()] attribute )
Just remember that your models should not contain any persistence logic at all.
I think it is pretty typical of any "real world" application to store data differently than is displayed on the screen. I think you are on the right track, with having 2 seperate "models". I usually end up calling them:
ViewModels - map to what is displayed on the screen, what the views want.
DataModels - map to the DB, what the persistence layer (ORM) wants.
Sometimes the DataModels are called Entities especially when talking about Entity Framework as a data access layer, or Data Transfer Objects (DTOs).
Usually there is some set of "translators" to map from the view to the data models too, or sometimes AutoMapper can be used.
Of course if what you are displaying is close enough to your data structure, there is no harm is passing all the persistence / data models to the Views, but I like to keep them separate too.
I’ve considered some of the ideas in the Onion Architecture (namely dependency injection) to solve this, but it seems that a more elegant /obvious solution might be available.
Once you get the hang of using Dependency Injection correctly, it's really a very elegant/obvious solution.
I'd suggest a dependency structure like this:
UI
Controllers -> Services, Models, ViewModels
Views -> ViewModels
ViewModels (no dependencies)
Services -> Repositories, Models
Repositories -> Models
Models
This is pretty close to what you had before, but your ViewModels are a part of your UI project and have no dependencies at all. They should just be simple classes that represent what you want to show to the user.
It's the Controller's job to:
Invoke the services to get the Models,
Translate the models into ViewModels, and
Invoke the View code
Views should not require any information that isn't provided by the ViewModels.
Should the model just be data structures? Where do the services (data access, business logic) sit in MVC?
Lets assume I have a view that shows a list of customer orders. I have a controller class that handles the clicks on the view controls (buttons, etc).
Should the controller kick off the data access code? Think button click, reload order query. Or should this go through the model layer at all?
Any example code would be great!
Generally I implement MVC as follows:
View - Receives data from the controller and generates output. Generally only display logic should appear here. For example, if you wanted to take an existing site and produce a mobile/iPhone version of it, you should be able to do that just by replacing the views (assuming you wanted the same functionality).
Model - Wrap access to data in models. In my apps, all SQL lives in the Model layer, no direct data access is allowed in the Views or Controllers. As Elie points out in another answer, the idea here is to (at least partially) insulate your Controllers/Views from changes in database structure. Models are also a good place to implement logic such as updating a "last modified" date whenever a field changes. If a major data source for your application is an external web service, consider whether wrapping that in a model class.
Controllers - Used to glue Models and Views together. Implement application logic here, validate forms, transfer data from models to views, etc.
For example, in my apps, when a page is requested, the controller will fetch whatever data is required from the models, and pass it to a view to generate the page the user sees. If that page was a form, the form may then be submitted, the controller handles validation, creates the necessary model and uses it to save the data.
If you follow this method, Models end up being quite generic and reusable. Your controllers are of a manageable size and complexity because data access and display has been removed to Models and Views respectively, and your views should be simple enough that a designer (with a little training) could comprehend them.
I wouldn't put Data Access Code in the Controller.
To build on what has already been said, it's important to think of layering WITHIN the layers. For example, you will likely have multiple layers within the Model itself - a Data Access Layer which performs any ORM and Database access and a more abstract layer which represents the Business Objects (without any knowledge of HOW to access their data).
This will allow you to test the components of your system more easily, as it supports mocking.
I like to keep the "contracts", or interfaces, for model persistence or service access in the domain (model) layer. I put implementations of data access or service calls in another layer.
The controllers are instantiated with constructors that take interfaces for the services, e.g. ISomeService, as parameters. The controllers themselves don't know how the service layers are implemented, but they can access them. Then I can easily substitute SqlSomeService or InMemorySomeService.
I've also been fairly happy with a concrete service implementation that takes a domain (model) layer repository as a parameter to its constructor.. For example: ICatalogRepository with SqlServerCatalogRepositry : ICatalogRepository is handed to CatalogService(ICatalogRepository, ISomeOtherDependency).
This kind of separation is easier with dependency injection frameworks.
The View would relay what should happen on a click in the UI to the Control layer, which would contain ALL business logic, and would in turn call the Model layer which would only make database calls. Only the model layer should be making database calls, or you will defeat the purpose of the MVC design pattern.
Think about it this way. Let's say you change your database. You would want to limit the amount of code change required, and keep all those changes together without affecting other pieces of your application. So by keeping all data access in the Model layer, even the simple calls, you limit any changes required to the Model layer. If you were to bypass the Model layer for any reason, you would now have to extend any changes needed to any code that knows about the database, making such maintenance more complex than it should be.