I am writing a smart client WPF application using MVVM that communicates with a WCF service layer containing the business logic and domain objects that uses NHibernate to manage persistence. We are in control of both sides of the wire.
Currently, I am working on creating a screen to Edit Product Details it has a tab control with each tab representing some aspect of the Product such as Main Details, Product Class, Container Type and so on. In the end, there will probably be at least 5 of these tabs.
Up to now I have been working on transforming simple domain objects to DTOs using SetResultTransformer and this has been working quite nicely.
Now that I am getting to a more complicated object I am getting a bit stuck. I would like to return a DTO to be displayed that contains the Main Product details, categories and classes. As far as categories and classes are concerned I would not want to return every single property of the domain object.
Questions:
1) How do people go about creating a DTO where there are several one to
many collections to return as in this example?
2) Is there any concerns about the DTO becoming too large?
3) When sending the DTO back to the back end is it better to send the same type of DTO with the updated values or some other more command oriented DTO?
Thanks for any help
Alex
We are currently using pretty big DTOs and it is working pretty fine. NHibernate is doing a lot of lazy loading, so this helps with big objects.
We are using bags for one to many relations, they are lazy loaded and are working pretty well.
Depending on the type of application lazy loading can be a bit of a problem. We had some problems with our rich client application with big DTOs but with some planning and a sound architecture it works pretty well.
I don't know if large DTOs are really a problem with NHibernate, but so far we don't have got any problems.
We are sending the whole object back and forth and it is doing well. NHibernate updates just the changed fields and this is really nice.
I wouldn't serialize the NHIbernate objects over web services or something like that (I don't know the WCF service layer and how it communicates with your application). If I am transferring data through web services I am generating new data objects and fill them accoringly, transfer them back and forth and update the NHibernate objects with those.
Have you tried Automapper? I do all my DTO mappings with Automapper and it works like a charm.
Have a look at automapper. I'm sure you'll like it.
Related
I am using AutoMapper.org to map my DTO objects to Model objects in MVC4. DTO objects are retrieved from SOAP web services. The operations on the services are mostly CRUD.
This works nicely.
I have 2 questions. Firstly, is it bad practise to map both ways (2 way mapping). So when I update on screen map the Model to a DTO, as well as the orginal mapping of DTO to Model?
Second question, is it possible for AutoMapper to map enums?
I map both ways without issue - I map from the DTOs to the business objects to get the data, and map back the other way to save the data. This is so that the DTOs that are used in my WCF service are reusable (I'm using CSLA framework and the data portal model in CSLA doesn't really let 3rd parties consume the service without having access to my bizobj library).
It does mean that some of the business logic is repeated in the web layer, but since the rules are sparse this isn't a big issue
In my case I don't think it's a bad thing. I have a very simple data model which is mostly reads, there is only the occasional time when data goes back across to be modified.
As far as I know it maps enums natively (assuming it's a direct enum to enum - since enum is just a primitive underneath), but you can always provide your own custom type converters to resolve any enum issues or if you need to do string parsing for enums.
Please help on choosing the right way to use the entities in n-tier web application.
At the present moment I have the following assembleis in it:
The Model (Custom entities) describes the fields of the classes that the application use.
The Validation is validating the data integrity from UI using the reflection attributes method (checks data in all layers).
The BusinessLogicLayer is a business facade for additional logic and caching that use abstract data providers from DataAccessLayer.
The DataAccessLayer overrides the abstarct data providers using LinqtoSql data context and Linq queries. And here is the point that makes me feel i go wrong...
My DataLayer right before it sends data to the business layer, maps (converts) the data retrieved from DB to the Model classes (Custom entities) using the mappers. It looks like this:
internal static model.City ToModel(this City city)
{
if (city == null)
{
return null;
}
return new model.City
{
Id = city.CountryId,
CountryId = city.CountryId,
AddedDate = city.AddedDate,
AddedBy = city.AddedBy,
Title = city.Title
};
}
So the mapper maps data object to the describing model. Is that right and common way to work with entities or do I have to use the data object as entities (to gain a time)? Am I clear enough?
You could use your data entities in your project if they are POCOs. Otherwise I would create separate models as you have done. But do keep them in a separate assembly (not in the DataAccess project)
But I would not expose them through a webservice.
Other suggestions
imho people overuse layers. Most applications do not need a lot of layers. My current client had a architecture like yours for all their applications. The problem was that only the data access layer and the presentation layer had logic in them, all other layers just took data from the lower layer, transformed it, and sent it to the layer above.
The first thing I did was to tell them to scrap all layers and instead use something like this (requires a IoC container):
Core (Contains business rules and dataaccess through an orm)
Specification (Seperated interface pattern. Contains service interfaces and models)
User interface (might be a webservice, winforms, webapp)
That works for most application. If you find that Core grows and becomes too large too handle you can split it up without affecting any of the user interfaces.
You are already using an ORM and have you thought about using a validation block (FluentValidation or DataAnnotations) for validation? Makes it easy to validate your models in all layers.
It may be a common practice to send out DTOs from serivce boundary (WCF service, etc.) but if you are directly using your "entities" in your presentation model, I don't see any benefit in doing that.
As to the code snippet you have provided, why not use AutoMappter? It helps by eliminating writing of boiler-plate mapping codes and does that for you if you have a set of convention in place.
Get rid of the model now, before removing it later will require refactoring the whole application. The last project i worked on used this architecture and maintaining the DTO layer and mappings to the database model layer is a huge pain in the arse and offers no usefull benefits. One of the main things that is anoying is that LinkToSql does not effectively support a disconnected data model. You cannot update a database table by creating a new DB entity with a primary key matching an existing record and then stick it into the data context. You have to first retrieve the entity from the database, update it then commit the changes. Managing this results in really nasty update methods to map all the properties from your DTOs to your LinqtoSql classes. It also breaks the whole deferred execution model of LinqToSql. Don't even get me started on the problems it causes with properties on parent classes that are collections of child DTOs (e.g. a customer DTO with an Orders property that contains a collection of order DTOs), managing those mappings is really really fiddly, i had to do some extensive optimisations because retrieving a few hundred records ended up causing LinqToSql to make 200,000 database calls (admittedly there was also some pretty dumbass code as well but you get the picture).
The only valid reason to use DTOs is if you want to have multiple pluggable Data Access Layers e.g. LinqToSql and NHibernate for supporting different DB servers. That way you can swap out the data access later without having to change any other layers. If you don't need to do this then save yourself a world of pain and just use the LinqToSql entities.
I have a graph of objects :
School-->Classes-->Students.
and I want to set it up in a way that I can send back school class to the client and it can access classes and students in a lazy-loading way.
is that possible ?
In brief: no.
You can either :
send back all the data needed (including classes and students with your school entity) in a single call ("eager loading")
or:
you need have to have separate methods on your WCF service to retrieve detail data in a separate call (something like: List<Class> GetClassesForSchool(int schoolId), List<Student> GetStudentsForClass(int classId))
Lazy loading per se only works as long as your Entity Framework object context is still around to be queried for more data - which is certainly not the case when you send entities across the wire using WCF.
I don't think so, because your entity is travelling across different tiers and the one with database connection won't be accessed without your interventation from any other tier.
You'll need to tailor your own solution to do that, or just use data-transfer objects, which will have the right information nor the one that may be useless for some view.
Update:
Read this article if you want to learn more about DTO pattern:
http://aspalliance.com/1215_Implementing_a_Generic_Data_Transfer_Object_in_C.2
I'm starting a project using EF 4 and POCO.
What is the best practice for sending data to the client ? Should I send the POCO or I should have a DTO instead?
Are there any issue I should be aware of when sending the entity (that is disconnected from the context) to the client ?
Is it a recommended practice to send the POCO to the client layer?
I believe that we are mixing 2 definitions here that don't have relation with each other.
DTO or Data Transfer Object is a design pattern, you can use it to transfer data between layers, and also they don't have behavior. Martin Fowler explains this very well at: http://www.martinfowler.com/eaaCatalog/dataTransferObject.html
In the other hand we have POCO or Plain Old CLR Object. But to talk about POCO, we have to know where it started, that is POJO, or Plain Old Java Object. Martin Fowler with two partners coined the term and he explains it here: http://www.martinfowler.com/bliki/POJO.html
So POCOs can have behavior and everything you want. They are the same common classes you write in your daily-basis, they just gave them that name to call them in a short and easy-remember way.
In anwser to your second question, I think the best approach and the one I always go for is sending DTOs from the Busines Layer to everything that uses it (e.g.: your services, web site, desktop app, mobile app, etc.). This is because they don't have behavior and not pretty much than only properties in most of the cases, so they are light-weight and ideally to use in services, and of course, they don't reveal sensitive data from your business.
That being said, if you are planning to use DTO, I can recommend you to download EntitiesToDTOs, an Entity Framework DTO Generator that I just recently published at CodePlex, it is free and open source. Go to http://entitiestodtos.codeplex.com
For me, one of the main reasons to use EF4 with POCO is the fact that you don't need DTO's. I can understand using DTO's with traditional EDMX files where your entities are pretty bloated, but this isn't the case.
Your POCO obviously needs to be serializable, but there really shouldn't be any issues specific to sending POCO entities that don't also occur with DTO's.
I have a bit different opinion from above opinions.
I believe DTO or ViewModel is still needed for out side of the Server Layer.
In real world application, there is a few view layer which only need one Domain Object, that is, almost every views need multiple Domain Objects.
And all those Domain Objects are wrapped in one DTO or ViewModel Class.
This is why I insist DTO or ViewModel is still needed even though they are POCO.
I would consider EF4 entities business models AND viewmodels rolled into one. They already implement PropertyChanged out of the box, for example. Partial classes can provide custom functionality if you need. Mirroring the entities with your own safety layer creates unnecessary work and maintenance, in my opinion.
I'm a believer in separation of business logic and everything else. However in the case of EF4 the work is already done for you. Go nuts.
I'm curious to know what the community feels on this subject. I've recently come into the question with a NHibernate/WCF scenario(entities persisted at the service layer) and realized I may be going the wrong direction here.
My question is plainly, when using a persistent object graph(NHibernate, LINQ to SQL, etc) behind a web service(WCF in this scenario), do you prefer to send those entities over the wire? Or would you create a set of lighter DTO's(sans cyclic references) across?
DTOs. Use AutoMapper for object-to-object mapping
I've been in this scenario multiple times before and can speak from experience on both sides. Originally I was just serializing my entities and sending them as is. This worked fine from a functional standpoint but the more I looked into it the more I realized that I was sending more data than I needed to and I was losing the ability to vary the implementation on either side. In subsequent service applications I've taken to created DTOs whose only purpose is to get data to and from the web service.
Outside of any interop, having to think about all the fields that are being sent over the wire is very helpful (to me) to make sure I'm not sending data that isn't needed or worse, should not get down to the client.
As others have mentioned, AutoMapper is a great tool for entity to DTO mapping.
I've almost always created dtos to transfer over the wire and use richter entities on my server and client. On the client they'll have some common presentation logic while on the server they'll have business logic. Mapping between the dtos and the entities can be dumb but it needs to happen. Tools like AutoMapper help you.
If you're asking do I send serialized entities from a web service to the outside world? then the answer is definitely no, you're going to get minimal interoperability if you do that. DTOs help solve this problem by defining a set of 'objects' that can be instantiated in any language whether you're using C#, Java, Javascript or anything else.
I've always had problems sending nHibernate objects over the wire. Particularly if your using a ActiveRecord model. and/or if your object has ties to the session (yuck). Another nasty result is that nHibernate may try and load the object at the entry of the method (before you can get to it) which can also possibly cause problems.
So...getting the message here? problems, problems problems...DTO's all the way