In my client application I have a View, ViewModel and a Service Layer DTO as my Model.
My issue is this particular view must also consume a whole bunch of other services in order to populate some drop down lists, so now my ViewModel has references to multiple DTOs. Is this good practice? or should the WCF return a single DTO that contains everything the ViewModel needs?
That's fine, as ViewModel is just another abstraction. It's a Model for a certain View and can be composed from multiple DTOs.
The ViewModel's task is to prepare the data to be displayed by the View, so if composition of multiple DTOs is necessary to be consumed and displayed by the View, then it's okay to do it.
Related
Let's say you have three models, Organization, OrganizationUser, and User.
You need to handle the following reqs:
When a user creates an organization, they should become a user associated with that organization (a row in OrganizationUser table).
If any of the operations above fail, the entire "flow" should fail. This should be implemented with a transaction.
Here are the three best ways I think you can architect it:
In the controller, create TXN, pass it to the Organization and OrganizationUser models to create their respective rows. Rollback if needed. Controller contains the business logic (has user paid, what type of org... etc).
In the controller, call CreateOrganizationService which handles the transaction creation, abstracting it away from the controller; passes it into the models. CreateOrganizationService is where we'll keep most of the business logic
Have Organization model require OrganizationUser model and take care of the transaction creation, the business logic, and creation of the OrganizationUser row.
Is there a better way of thinking about this, or different approaches/patterns I can apply?
The Controller's job is to translate incoming requests into outgoing responses. In order to do this, the controller must take request data and pass it into the Service layer. The service layer then returns data that the Controller injects into a View for rendering.
The model in MVC is not a class, it's a layer.
The Model's job is to represent the problem domain, maintain state, and provide methods for accessing and mutating the state of the application. The Model layer is typically broken down into several different layers:
Service layer - this layer provides cohesive, high-level logic for related parts of an application. This layer is invoked directly by the Controller and View helpers.
Data Access layer - (e.g. Data Mapper) this layer provides access to the persistence layer. This layer is only ever invoked by Service objects.
Value Objects / Entity layer - this layer provides simple, data-oriented representations of "leaf" nodes in your model hierarchy.
To your question: Don't put business logic or transactions into the controller. Put the business logic (and transactions) stuff into the Service class (part of the model layer).
Source
You can implement a service layer in between controller and repository where you can handle the business logic and making the controller clean. And all the operations related to database (CRUD) can be done in repository.
Refer this :
Difference between Repository and Service Layer?
from your controller, you can call:
svc.CreateOrganization(<params>);
I probably wouldnt pass the model into the service. I would pass the actual data parameterized out for each piece of data b/c inside of your CreateOrganization call you should be calling into the data access layer which should use DAOs to store data.
I have an ASP.NET MVC 4 project, where Controller calls a WCF Service layer, that calls Business Layer, that use a Repository of EF 5.0 Entities. Then the results are returned as POCO entities to the Controller.
It works fine while the WCF Service is directly referenced as a Library, but I know it won't work referenced as a Service because they will need to be serialized, and with ProxyCreation enabled this is not possible.
I don't want to create DTOs because I use generated POCO entities, that's why they exist in my humble opinion.
I want to track changes only before the POCO entities reach Service layer.
A lot of people talk about using DTOs even when they are identical to POCOs, if I do that, I could create auto-generated copied classes just with different names to be a "Proxy disabled POCO as DTO", what would be a little strange.
Could I kill the proxy class of a POCO, in a way the object could be serialized when returned from the Service layer?
Also I don't know if this idea is a good practice. But would be great to send "clean" entities to my Controllers, ready to me mapped to ViewModels.
I'm looking for performance too.
The problem is solved using ProxyDataContractResolver. We must use [Serializable] and [DataContract(IsReference=true)] too. With this combination, ProxyCreation can be enabled.
The way we handled this was by doing the following:
Customize the T4 generating the POCO classes so that it generates classes decorated with
[Serializable()] and [DataContract(IsReference=true)] attribute.
Both frontend (views) and backend (wcf service / business layer) references the POCO generated classes, since you won't be using proxy due to IsReference=true.
and that's basically it.
With this, you don't have to create DTO and just use the POCO classes both in backend and frontend.
Keep in mind though, that WCF using IsReference=true handles does not like redundant objects (so this would be an issue on some POCO classes with navigation properties).
I have asp.net mvc 2 application. i have confusion creating DTO and domain entities.
MVC Controller Integration points:
1) third party WCF
2) DB Layer
WCF is returning Persons information of a particular company and some information about company.
I have generated proxy of WCF and written a service wrapper on the proxy.
Service wrapper is talking to WCF and Mapping the results to DTO clas ContactsDTO
Service layer is in different project.
Following are my domain classes
Company
Person
DTO class
//it contains
class ContactsDTO
{
Person person, Company[] company
}
Controller action calls the wrapper with companyID and get the object of DTO class.
and update the company information from dto. it updates the company information in Session and pass the Company[]array to some other operations.
DB interaction:
Now depending upon some business logic, i have to insert Person-ids and company id along with some other information in Database.
for this i have created another
class DBDTO
{
Person person, Company[] company, OtherInfo otherInfo[]
}
this DBDTO is prepared and passed to DB Layer(which is using Linq to sql).
Questions
Is it write way to do. Any improvement in DTO interaction? What all
changes i can do to improve the overall architecture
Another alternative to DB-bound objects being translated to DTOs (which takes time) is to use POCO (Plain Old CLR Objects) and use them directly as your Domain Model, objects that can be stored in the DB and objects that are communicated to Controllers for visualization.
This can get you started: Working with POCO Entities
This approach has several advantages
Your POCO entities are independent of the underlying DB implementation
Your POCO entities can be unit-tested without presence of a Database
You can easily serialize them into a service response (if you are building an API) using DataContractSerializer or DataContractJsonSerializer
I agree with Algirdas to differentiate models because of different responsibilities.
By the way: MVC is not a layer concept. It's a concept of three responsibilities and their collaboration. Although it is often (mis)used for layering you will encounter problems with SRP if you only separate your application layers applying "MVC". If you have MVC per layer then you go well.
After all if it is a small application you maybe never reach the critical mass to have problems with the architecture.
I have business layer and UI layer in separate projects within a same solution. What i need is ,connect this UI with business layer which coded in c#. UI created using MVC3 Razor.
What i should use as model in MVC application? am i need to create Service reference to business layer to generate some proxy?
then can i use those proxy as a model? please help me..
if you can provide me some tutorials
i tried this but no more idea with MVC :
http://www.dotnetfunda.com/articles/article816-understanding-the-basics-of-wcf-service-.aspx
Unless your project (or architect) demands that all methods of your app access a services layer, I would try and avoid using WCF unnecessarily (think of it - it means that all of your data between web server and back end goes over the wire, which has implications such as performance, serialization of data, and also potentially limits the lifespan of database connections and transactions, which can deprive such as lazy loading).
If you concur, the suggestion would be to ensure all accessible interfaces in your business layer are exposed on an interface, and then consume or inject the BLL interface directly into your controller.
You need to be careful about the word "Model" in MVC - ASP NET MVC encourages ViewModels, which are specific to the presentation tier and passed between Views and Controllers, as opposed to "Entities" which represent the more logical domain model as used by business logic and which can be tied to data persistence using an ORM such as EF or NHibernate. The MVC project template lumps everything which isn't View or Controller into "Model" which isn't necessary very helpful.
However, if you do choose to access your BLL via a WCF Services layer you still have some design decisions to make:
Choose whether you share the back end entities on the client side, or do you instead use proxied entities.
Choose whether you consume / inject the WCF service proxies directly in your controller, or do you create another facade layer (e.g. CAB calls these ServiceAgents). The latter would make sense if there are separate teams or vendors building the SOA side vs the Client side in order to accomodate changes to interfaces.
In my application I am making a service call and getting back populated WCF Data Contract object. I have to display this data in a grid. Is it good practice to bind the data contract to the grid ?
Josh
Is it good practice to bind the data contract to the grid ?
Yes. There is nothing wrong with what you are doing.
Let me elaborate: what you have received back from the WCF service is a standard object (sometimes referred to as a DTO - Data Transfer Object). You have not received a DataContract - you have received an object that used a DataContract to control the serialization process between the WCF service and your client. The DataContract can control or dictate what you get, but once you have that object you are free to treat it as you wish.
Assuming that all of your DTOs are friendly for data binding then shouldn't have a problem binding your WCF DTOs to a grid.
Some scenarios where you might not want to bind directly to your DTOs are:
Your DTOs are not easy to bind with their current definition (e.g. nested objects/properties)
You need to support notification of changes to the binding client (typically done using INotifyPropertyChanged)
You wish to insulate your UI code from changes to the WCF DTOs. This could be because you don't control the DTO definition or you expect frequent changes to the DTO definitions and you don't want to frequently change your UI code. Of course, if the DTO does change then you will have to modify code but you could isolate those changes to a small translation layer.
I'd recommend the use of view models for any data binding or data display (MVVM) on server side (i.e. MVC) and client side (javascrip) rendering.
The main risk of using DTOs returned by domain is that if DTOs are refactored for any reason (i.e. properties are renamed, extracted into other objects or more objects are merged into one) the UI will break and will require update.
DTOs are the contract for what is returned by your domain, whereas the view models are the contract for what the UI requires. The two are controlled by different requirements and although those requirements can be applied to the same set of objects the result is usually a mixture what is just wrong, not to mention that requirements what apply only to UI or domain will trigger changes in the other party.
I.e. views often require data from more DTOs, or different views require a different subset of data from the same DTO and in both cases the DTO should not change only to accomodate what a concrete view requires.
It is also easier to identify what the requirements for a view are if the views have a view model, rather than having the same DTO passed in to more views.