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.
Related
I have three projects:
WCF Service project (Interface and Implementation)
aspx web project (client) that consumes the WCF Service
class library project that holds my business objects (shared by both WCF project and client)
I have a method in the WCF Service implementation class file that retrieves a generic list of data from SQL (referencing the project that holds the business objects), serialize the data using System.Web.Script.Serialization.JavaScriptSerializer and returns the result as a string.
The web client takes this string and deserializes it back to the appropriate business object (referencing the project that holds the business objects)
This is an intranet app and I want to make sure I am doing this correctly.
My questions are:
Should I be using DataContracts instead of business objects? Not sure when to use DataContracts and when to use the business objects.
If I am using DataContracts, should I not use
System.Web.Script.Serialization.JavaScriptSerializer?
Any clarification would be appreciated.
Of course there is no one answer. I think the question is whether you want to use business objects in the first place, otherwise my fourth point pretty much covers it.
Do use the business objects if they look like the data contracts would, i.e. they are a bunch of public properties and do not contain collections of children/ grandchildren etc.
Don't use the business objects if they contain a bunch of data you don't need. For example populating a grid with hundreds of entities begs for a data contract specific to that grid.
Do use the business objects if they contain validation logic etc that you would otherwise have to duplicate in your web service.
Do use the business objects if you are just going to use the data contracts to fully inflate business objects anyway.
Don't use the business objects if you ever want to consume that service interface from non .net code.
Don't use the business objects if you have to massively configure their serialization.
Don't use the business objects if they need to "know" where they are (web server or app server)
Not your case but: Do use the business objects if you are building a rich client for data entry.
Thats all for now, I'll see if anything more occurs to me. :)
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 an existing set of Services and Repositories I use in an MVC application that leverage the Entity Framework 4.1 Code First.
I want to create a couple of WCF Services that use the existing architecture, but it seems to have a hard time serializing the object graphs.
I realize that there are some circular references to deal with, but I really don't want to litter the Domain Objects with WCF attributes, so should I just create View Models like my MVC app uses? And if so, should I create the View Models to be able to be used in both?
Any other ideas? - Thanks!!
I prefer keeping my domain model and the WCF data contract separate by defining Data Transfer Object classes as the data contact of the WCF server. They are tailored specifically to carry the right data across the wire. A good DTO design will keep the number of WCF service call roundtrips from the client down. It will also separate your internal domain model from the contract with the client.
What are the pros and cons of using WCF Service with DataContracts VS Entity Framework Entities Object?
If i generate Data Contracts using ADO.net Self Tracking Entity Generator the classes in my data layer.
What will the best way of using it in my WCF service?
Will the datacontract genrated ADO.net Self Tracking Entity Generator will be exchnaged via the service or WCF service will still use the default Entity framework objects?
Main advantage of STEs (Self tracking entities) is implementation of change set. It means that you can return STE from web service's operation modify entity (or whole entity graph) and call another operation to post updated STE back to web service for processing. EF will automatically detect changes in STE and process them.
This is not possible with Entity Framework entities because it can track changes only if entity is attached to ObjectContext but the entity is detached when returned from web service operation.
Drawback of STEs is that you have to share assembly which defines them among service and all clients. STEs are not for interoperable solutions.
At the moment most projects are developed with third type of entities - POCOs. POCOs are also not able to track changes when detached from ObjectContext. It is the feature of STEs.
It depends on what type of work you are doing.
Using DTOs (Data Transfer Objects) which form your Data Contracts and are separate from the EF model will give you more control over what get serialized or not. This is important for compatibility and versioning with multiple clients.
http://martinfowler.com/eaaCatalog/dataTransferObject.html
Using EF with POCO is probably next in terms of control and separation with the default database generated form last. However these two are easier to use and more flexible when used with Silverlight clients.
I'm working on a project where I have an abstract class of Appointment. There are Workouts, Meals and Measurements that all derived from Appointment. My architecture looks like this so far:
Dao - with data access layer being entity framework 4 right now
POCO classes using the T4 templates
WCF
Silverlight Client, ASP.net MVP, mobile clients
Would I put business rules in the POCO class? or map my Entities to a business object with rules and then map those to DTOs and pass those through WCF?? and when I pass the DTOs do I pass over type Appointment? Or write a service method for each sub class like Workout or Meal?
I haven't found any good material using table per type inheritance and WCF.
thanks in advance!
-ajax
it mainly depends on complexity you require. You are using POCO classes it is good starting point. You now have to choose how complex application are you going to build, how much business logic do you want to add and what do you want to expose to your clients?
The POCO entity can be just DTO or you can turn POCO entity into business object by adding business methods and rules directly into that entity - you will transform the entity into Active record pattern or to Domain object. I don't see any reason to map your POCOs to another set of business objects.
Exposing POCO entity in WCF service is the simplest way. You can use operations which will works directly with Appointment class. Additionally you have to give your service information about all classes derived from Appointment - check KnownTypeAttribute and ServiceKnownTypeAttribute. Using entity often means that service calls transport more than is needed - this can be problem for mobile clients with slow internet connection. There is one special point you have to be aware of when exposing entity which is aggregation root (contains references to another entitities and collection of entities) - if you don't have full control over client applications and you allow clients sending full modified object graph you have to validate not only each entity but also that client changed only what he was allowed to. Example: Suppose that client want to modify Order entity. You send him Order with all OrderItem entities and each item will have reference to its Product entity = full object graph. What happens if instead of modifing Order and OrderItems client changes any of Products (for example price)? If you don't check this in your business logic exposed by WCF and pass the modified object graph into EF context, it will modify the price in your database.
If you decide to use your entities like business objects you usually don't expose those entities, instead you will create large set of DTOs. Each operation will work with precisely defined DTO for request and response. That DTO will carry only information which are really needed - this will reduce data payload for service calls and avoid passing modified prices of product, because you will simply define your DTO to not transfer price or even whole product from the client. This solution is much more time consuming to implement and it adds additional layer of complexity.
Because I have mentioned object graphs I must clarify that there is another hidden level of complexity when using them: change tracking. EF context needs to know what have changed in object graph (at least which OrderItem was modified, which was added or deleted, etc.) for correct persistence. Tracking and multi tier solution is a chalenge. The simplest solution does not track changes and instead uses additional query to EF. This query returns actual persisted state of object graph and modified object graph is merged with it (special care is needed for concurrency checks). Other solutions uses some tracking support in entity - check Tracking changes in POCO and Self-tracking entities. But this is only for entities. If you want to track changes in DTO you have to implement your own change tracking. You can also read articles from MSDN magazine about multi tier applications and EF:
Anti-Patterns To Avoid In N-Tier Applications;
Building N-Tier Apps with EF4