Is that acceptable to pass directly domain model entity to UI layer instead of corresponding viewmodel?
In my example UI gets some user data and passes it down to presenter which interacts with domain service. Domain service performs some action on the data from the user and returns output results back to UI as domain model entity, which should be typically converted to viewmodel.
The problem is that depending on the user choice (Y or N) inspecting the returned result, it may be returned back to the service for further processing and finally saved to repository.
If we do not save returned domain entity somewhere between those 2 steps, but use viewmodel, we will not be able to pass it back for further processing.
Are there some workarounds when such user interaction takes place?
MVP is defined around the concept of View, Presenter, and Model. There's no reason you need to distinguish between a domain entity and a view Model. They can (and should) be the same thing.
Unlike MVVM, the model plays less of a role in binding to the View. It's the responsibly of the presenter to manipulate the view using the model data. There is no concept of a ViewModel as such in MVP. That term is generally reserved for MVVM where ViewModel is an entity tightly coupled to View, in addition to having a Model.
I would rather recommend separating the presentation model from domain model either in terms of view model (in MVVM) or in terms of Model in MVC / MVP, because in medium to high domain complexity you design domain model in terms of business logic and object oriented design which has a granularity level other than presentation data, when you bind or present data you tend to show part of domain model and flatten some objects to be continent for presentation.
Another aspect is when developing distributed application sometimes you need to expose your data through services (remote facade) thus it is highly preferable to expose your objects in terms of DTOs not to expose you domain model because again the aspect of DTO is different in complexity and granularity than the domain model, dont force your domain model to be corrupted to be presentation friendly or consumer friendly, and dont corrupt your presentation model and consumers to use a business oriented domain model and increase the complexity of adopting them for presentation.
Related
I am working on understanding MVVM better, and from trusty Wikipedia (and lots of other research), I have gathered that the ViewModel holds presentation logic and the Model holds the business logic.
MVVM Pattern (Image courtersy of Wikipedia)
My question is, how is there a separation of concerns between logic and data when the Model is holding the business logic? Why is this a good pattern and why would I want to use it instead of using MVC where the Controller handles business and presentation logic (if I understand it correctly)? (I am using WPF, which based on my research, mainly uses MVVM and rarely uses MVC, and I still don't understand why).
Separating presentation logic from business logic allows you to change business logic without directly affecting presentation logic.
For example, if you have a RESTful web API that retrieves some data a view should render, the ViewModel should not be directly handling the HTTP operation or any translation of the incoming data. The ViewModel should ask a (separated) service class to retrieve that data and then the ViewModel can choose how to present that data, such as by pagination, sorting, filtering, and so on. You may choose to paginate at the web API level instead, but that's an implementation detail. In the event that your API contract changes, you can change the web API service without affecting the presentation logic: separation of concerns.
Let's get some things straight:
MVC = Model View Controller
MVVM = Model View ViewModel
With MVC, the controller controls the data and the business logic, the model stores the data temporarily, and the View can read the data from the model. In this model, the View handles the presentation logic. In C#, you can use Razor Pages (.cshtml) to dynamically insert values into the view.
MVVM is very similar. The Model is responsible for holding the data and business logic, the View Model holds the data temporarily, and the View controls the presentation logic. The main difference is the physical separation in your code.
With MVC, each step is separated into its own file. With MVVM, usually two or more steps are combined together into one file. This can be advantageous because it keeps you from having controllers that are hundreds or thousands of lines long if you have lots of pages. I personally still like MVC, because it keeps everything separate instead of combining it together.
I am looking to implement the Onion Architecture into our ASP.NET MVC application. I understand the need to separate View Models from Domain Entities, however I am finding myself writing redundant code. There is redundant code because my view models and domain entities look exactly the same with the exception that my view models have the [Serializable] data annotation. I need these models serializable because I am using ASP.NET Session State in which the State Server needs objects to be serializable.
I personally feel the domain entities should NOT be serializable because it would then become dependent on a particular technology. However, how can I avoid redundant code?
I should add that my service methods are dependent on these serializable data models.
I would avoid annotating my domain objects with anything persistence or non-domain related. This way, my Domain project wouldn't depend on another layer and I won't have it cluttered with things that aren't relevant to the Domain. While we need to bend the rules, I prefer bending them in a way not involving dependency on a persistence detail.
The point is to keep the layers focused on their purpose because it's very easy to mix'em up and create (in time) the big ball of mud.
In your case, I have the feeling you don't really have a rich domain or it's improperly modeled. It seems you only have data structures and your needs are CRUDy.
If you are certain the app won't evolve to become more complex i.e it will be just data structure manipulations then you can have one model to use them for all the purposes. Basically you can cut corners and use the 'business' model for everything. No need for abstractions and other stuff.
But if you think the app will evolve or they are or will be business rules and processes i.e you'll need to model behaviour as perceived by the business, then it's best to keep things very decoupled, even if at this stage they seem to be identical.
To make it easier, for your view model you can define one (with copy paste) and use automapper to map the business object to the view model one. Other approach maybe that your query service/repository/object could return directly that view model (map the query result to the view model)
Viewmodels can contain domain entities/models. My domain entities are partial classes and all (eventually) inherit from a base entity which is serialized. Since I use my domain models within some of my viewmodels, I use data annotations on the domain models as well. Your domain model library should not depend on/reference anything else (domain driven).
I wouldn't call [Serializable] a data annotation per se, since it's part of the core .Net platform (mscorlib.dll). Data Annotations refers to specific attributes used to perform data validation and other operations in ASP.Net or Entity Framework.
Should an Entity be [Serializable] ? Probably not, but I don't think this attribute is as "adulterating" to your domain layer as other attributes that come from external, web- or persistence-oriented libraries. It doesn't tie you to a particular third-party framework.
The whole "redundant code" issue depends IMO on the type of system you're building. In a genuine DDD application, duplication between Domain entities and View Models will probably not be all that blatant, and the benefits of a separate presentation model will typically outweigh the costs. A good article on that subject : Is Layering Worth The Mapping ?
When implementing Repository for database in ASP.NET MVC project, is it correct to place business logic into it or may be better to place logic in controller class? Or use additional service and helper classes for manipulating data?
Ultimately there isn't a perfect place for your business logic besides its own layer (as part of the "Model" layer). Often you can get away with a different implementation, but there are trade offs in every case.
The trade off to creating another layer for the business logic is that you have to actually encapsulate your code. If you're too aggressive, you might also get some duplication between your entities and your domain model (if your DB's relational semantics already take care of your buiness logic).
View
The view is the most brittle part of your app, as it is the most likely part to change.
It is also very hard to get business logic correct in your view, due to having to support all the various view state transitions.
It is extremely well known these days that you just don't do this :)
Repository
The issue here is one of maintenance and purity of abstraction. Violating this can confuse people and make your app hard to maintain.
From the P of EAA article on the Repository pattern:
A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection
A repository is an abstraction that presents your data storage as a collection that holds domain objects.
No domain logic should reside in it. Instead, it should exist in your domain objects (by definition, as your business logic is your domain).
To do otherwise (to make your repository do double duty and also validate domain logic) would be a violation of SRP (Single Responsibility Principle), and would be a code smell.
You can have higher level domain objects that work with collections of domain objects to validate domain logic (such as dependencies within a collection of objects, size limits, etc). They will still use your repositories under the covers to do final storage/retrieval of domain objects, so they won't be doing double duty (so won't violate SRP).
Controller
The controller is also not a good place to put business logic. The controller's job is to mediate between the controller and the model.
The model is the domain, and the domain is your business logic.
Entities
You might consider putting domain data in entities.
But you must be careful when accessing navigation properties if the entities are attached, as you can trigger inadvertent DB queries or exceptions (depending on if your context is disposed or not). Detaching them is also a problem, as it destroys your object graph unless you explicitly reattach the objects to each other after detaching them from the context.
If you make separate domain model classes, you might consider treating entities as DTOs only.
Edit: IValidatableObject
I found out just now about a feature in Entity Framework 4.1 that you may want to check out: the IValidatableObject interface.
You can make your entities partial classes, and in the partial class, implement this interface. When you do, the Entity Framework will call Validate on save, and you can call Validate whenever it makes sense for you to do so.
This might help you avoid splitting your persistence model from your domain model in additional cases.
See this article: http://msdn.microsoft.com/en-us/data/gg193959
Side note: Views/View Models
In case you are thinking about it, I suggest you avoid the temptation to pass entities back to the view. It will break in a lot of cases (e.g. Javascript serialization to store view state), and cause unintentional DB queries in other cases. Pass back simple types instead (strings, ints, lists, hashsets, dictionaries, etc), or construct view model classes to pass to the view.
Add a Service Layer to pass models to Repository, where Service classes corresponding to the controller can be added. For example if you use a UserController and User Model, You can pass the User Model to UserService class.
Here the Service Layer can act as a bridge between the Repository and the controller so that the separation of Controller and Repository is well established.
Business logic should be there in your Domain model.
Please look into this answer.
ASP.NET MVC - Should business logic exist in controllers?
I agree with the above, controllers should not be responsible for business logic simply for returning the appropriate views. I use a service layer to provide business logic and view model creation so that a controller simply passes the model returned from a service to a view.
I also ensure my view models are simple DTOs, and the service simply knows how to populate the properties appropriately.
In my opinion it depends on the business logic. Is the logic based on validation of input and input rules, if so it may be best to be on the model. However, if it is business rules based on workflow then that may need to be in a controller, such as, user chooses option A then gets redirected to a different page/form than if option B was selected. If the business rules have to deal with data persistence then it may need to go in the repository (It would seem strange to put it there to me). There's a ton of discussion about this, but it comes down to you or your team's perspective about how maintainable and flexible the end product will be based on the implementation.
Unless I misunderstand - Most of the articles I read on MVVM explains model in MVVM as the piece holding domain/business-logic, but what baffles me is that MVVM is a presentation layer pattern and presentation layer does not hold business logic in entirety. Can some please help me understand how the domain-logic in business layer maps to the model in the presentation layer, is the model in MVVM actually a DTO?
I'd appreciate if some one can help explain with an example how business layer is mapped to a MVVM model in SOA (business logic sits behind a web service). Thanks.
MVVM, like MVC, is just a form of Separated Presentation in which the intent is to achieve separation of concerns between the part of the applicaton concerned with the logic and state of the UI and the part of the application concerned with the logic and state relating to the business domain. So MVVM doesn't really dictate anything about the form that the Model part takes as long as it is separated from presentation concerns.
The Model is purposely not coupled or dependent in any way on the presentational aspects of the application but beyond that there are many different ways to implement the "M" part of the triad. In particular, it doesn't have to map to a single object: it could mean interacting with a service that returns DTOs, it could mean publishing and subscribing to messages on a message bus or it could mean retrieving domain objects that represent entities in your domain, calling methods on them and then persisting them.
What's really unique about the MVVM pattern is the ViewModel's role in it since its purpose is to represent the state of the UI in a way that can be consumed by View technologies that have rich databinding capabilities. Without rich databinding support you would use a different form of Separated Presentation such as MVC or MVP, but the "M" part could still be the same because it's independent of the UI technology by definition. That is the important factor.
The Model in MVVM is not at all the DTO. DTO is the Data Transferable Object. Its more like the entity classes. It is basically used to transfer data from one layer to other layer; such as Presentation Layer to Business Layer or Business Layer to Data Access Layer.
And the Model mainly consists the Business Logic. Presentation Layer through View Model calls the Business Logic of Model as and when required.
Very often Model is encapsulated by ViewModel itself. You have to separate Model and ViewModel when by design it could be that single ViewModel uses different Models. But really this is a rare case so ViewModel can directly work with services.
If single ViewModel can serve different kind of Models which could be substituted one by one - introduce separate layer of Models, abstract them by interfaces and inject into appropriate ViewModels otherwise View and ViewModel is enough.
I have an ASP.NET app with a three layer architecture:
Presentation layer: ASP.NET
Bussiness Layer: C# library.
Data Access Layer: C# library with
ADO.Net Entity Framework objects.
Some methods on Bussiness layer would return ADO.NET entity objects but, data access layer is not visible at Presentation layer I can't do that.
My question is: On a design view, Is it correct to expose Entity Objects in the Presentation Layer? I think I only have to link Data Layer library with ASP.NET app.
Thank you!
It's absolutely desirable to have your entity objects available for use and consumption in your presentation tier. That's what all the work is for.
Binding collection of objects to a grid/listview/dropdown
Splashing a single object (i.e. customer) onto a form for read/update/delete
This makes your life easier by far. Otherwise you'd have to pass string after int after double after string between your presentation and business layers.
These may be Entity objects or even your own POCO objects that were hydrated from the Entity objects.
I would even go so far as to say that your Entites should be in their own assembly separate from the DAL.
I suggest that you look into the concepts of View objects...or Data Transfer Objects (DTO). You might consider using a tool like AutoMapper or similar which will create a view specific domain object out of your entities. In general you may have screens that need an entity present to perform its work. But more often than not you will need to pass several different entities. In this case you are better off creating one DTO that contains all of these entities. By doing this you are adding a layer of separation between your presentation layer and your business layer. Often times your entities have more power than you might want to expose to your presentation layer. And...vice versa. Frequently you may need to get some UI messages out to the presentation layer based on some validation flagged in your business layer. Rather than make your ui more complex than it needs to be (by passing in your full entities) you can only pass in what the UI needs in the form of the DTO. Also, there is never a need for your business objects to care about anything specific to the presentation layer. I suggest that you not databind directly to anything as far back as the data access layer. Technically your presentation layer should know as little as possible about your business layer. In the case of MVP or MVC this is very easy to achieve by disconnecting the front end and the back end by way of this additional separation!
I think no, it is not, the best way to do that is to separate data classes from behavior, and reference only data classes in presentation level.The good approach I think to use WCF see this link
See Supervising Controller and Passive View
If you pass the Entity, you are essentially Supervising controller. Otherwise you are Passive View.
Supervising controller is less work, but less testable. Supervising Controller also says databinding is OK.
Passive view is testable but a LOT more work. No databinding. Lots of properties.
Typically I stick with Supervising Controller. You typically don't need that level of testability and it isn't worth the extra trouble.