There are some pain points around transmitting entities between a client and a WCF service.
Defeating lazy loading by serializing all properties
Serialized data can be unecessarily bloated
Some coupling between UI and business layer
One way to address these issues is to transmit DTOs instead of entities but I am aware that this technique has its own set of caveats (the biggest one I am aware of is the typing required to maintain these function-specific DTOs).
I think it would be great if the service implementation could generate these DTOs dynamically and this appears to be possible. Unfortunately, it looks like the contract would be loosely defined on the client side (i.e. "object") and that smells like a possible risk.
Is it advisable to use dynamic DTOs in this fashion or is there another way to use DTOs without creating/maintaining classes for each one?
I think the holy grail would be where the implementation dynamically generates DTOs but the client sees well-defined contracts. I'm guessing this isn't possible with WCF.
I guess the issue is what are you going to generate them from? You have to have some description somewhere of what the data you want to transmit looks like. If all you have is the domain objects then you end up in a similar position of transmitting the data that you would of via the domain object.
One of the key things the DTO enables is decoupling so you can evolve your domain objects without breaking the consumers of your service accidently. If you dynamically generate the DTOs then you will cascade the changes - unless you view the dynamic creation as a one-off exercise to get you started with a DTO
DTO is data contract as any other and must be defined. When you choose to go with DTOs you are adding a layer of complexity which you have to maintain. There are tools which can help you with mapping between domain objects and DTOs (like AutoMapper) but your responsibility is to define what DTO should transfer - that is something which can hardly be done automatically. Even with automated tool you will still have to maintain some definition of DTOs which will be used to generate code.
Related
I am developing a Symfony-Application but I guess my question is mostly independent of
framework-usage.
This is the situation:
I got a very lightweight entity that is actually not even managed by the ORM as it is just used to aggregate and communicate information of another entity.
I read that we should keep business-logic out of the model but I also thought that it would
proof quite useful to me if I had a fromXYZ-method in my lightweight-entity to create a SPOC for instanciation based off of the "big entity".
But technically this from-method performs logic which contradicts what I read to be good practice.
So would this be an antipattern? How would I resolve this in a more suitable way, if yes?
What are you talking about is static factory method. It's pretty ok to use it, but it shouldn't do anything fancy because it will be hard to test your code since you can't mock it.
If you feel that your method won't create any problems in testing, you can create it without any doubt. Otherwise, you can encapsulate your creation logic in a separate factory.
Your "lightweight entity" could be referred to as a DTO.
One way to keep the terminology straight.
Entities are managed by the ORM.
DTOs are unmanaged. Often used to convey a subset or aggregation of entities.
Constructing one object from another by copying its fields is not something I would consider business logic, unless there are complex transformations prescribed by business requirements.
The real problem with fromXYZ methods is that they implement a dependency on XYZ. You have to be careful about which direction such dependencies are pointing. For example, if you construct a DTO by passing it an Entity, that DTO now has a dependency on the persistence layer of your application. If you then use that DTO in a service, your service layer now has a (transitive) dependency on your persistence layer. This is referred to as tight coupling.
One way to keep business logic decoupled from persistence, view, etc., is to point dependencies in the other direction: into the services rather than out of them.
I have taken a step back on two of the approaches in my project (WCF REST Service).
Started with WCFDataServices since it support full OData service stack, but due to more validation requirements on CRUD operations, switched to 'WCF Service' with EF.
And now thinking to step back to use Self-tracking entities to exposing entities to client, as many articles says STE is no more supported by Microsoft and preferred to use OData.(but again WCFDataService not suitable for me).
Please suggest what is the best design here to expose my entities over client.
Alternatively, I may have to write custom classes (Data Contracts) of Entity Model. But, this increases code (for conversion of objects between Custom and Entity) and decreases maintainability.
Please suggest is there any best approach to expose my entities. Your suggestions are valuable and most appreciated.
Fowlers first law of distributed object design states, "don't distribute your objects". This just means give them a copy and not the actual entity itself. If you were to create mirror copies of your entities in your data contract namespace, you retain much more flexibility, should your database schema need changing. If your data contract is initially identical to your entity, a tool such as AutoMapper will eliminate all the conversion code you need to write. Once configured, to convert your entity to your data contract becomes a 1 liner:
Mapper.Map<CustomerDto>(customer);
This takes your customer entity and gives you back a new customer dto. It's all convention based and works by matching up property names. Even if the data contract isn't entirely identical to the entity, you only have to prompt AutoMapper for those properties it can't figure out for itself.
I have a web client that calls my WCF business service layer, which in turn, calls external WCF services to get the actual data. Initially, I thought I would use DTOs and have separate business entities in the different layers... but I'm finding that the trivial examples advocating for DTOs, to be, well, trivial. I see too much duplicate code and not much benefit.
Consider my Domain:
Example Domain
I have a single UI screen (Asp.net MVC View) that shows a patient's list of medications, the adverse reactions (between medications), and any clinical conditions (like depression or hypertension) the patient may have. My domain model starts at the top level with:
MedicationRecord
List<MedicationProfile> MedicationProfiles
List<AdverseReactions> Reactions
List<ClinicalConditions> ClinicalConditions
MedicationProfile is itself a complex object
string Name
decimal Dosage
Practitioner prescriber
Practioner is itself a complex object
string FirstName
string LastName
PractionerType PractionerType
PractionerId Id
Address Address
etc.
Further, when making the WCF requests, we have a request/response object, e.g.
MedicationRecordResponse
MedicationRecord MedicationRecord
List<ClientMessage> Messages
QueryStatus Status
and again, these other objects are complex objects
(and further, complicates matter is that they exist in a different, common shared namespace)
At this point, my inclination is that the MedicationRecordResponse is my DTO. But in pure DataContracts and DTO and separation of design, am I suppose to do this?
MedicationRecordResponseDto
MedicationRecordDto
List<ClientMessageDto>
QueryStatusDto
and that would mean I then need to do
MedicationProfileDto
PractitionerDto
PractitionerTypeDto
AddressDto
etc.
Because I have show almost all the information on the screen, I am effectively creating 1 DTO for each domain object I have.
My question is -- what would you do? Would you go ahead and create all these DTOs? Or would you just share your domain model in a separate assembly?
Here's some reading from other questions that seemed relevant:
WCF contract know the domain
Alternatives for Translation Layer in SOA: WCF
SOA Question: Exposing Entities
Take a look on excellent articles
Why You Shouldn’t Expose Your Entities Through Your Services
DTO’s Should Transfer Data, Not Entities
above links don't work, looks like a domain issue (I hope it'll be fix), here is the source:
DTO’s Should Transfer Data, Not Entities
Why You Shouldn’t Expose Your Entities Through Your Services
I've always had an aversion to the duplicate class hierarchy resulting from DTOs. It seems to be a flagrant violation of the DRY principle. However, upon closer examination, the DTO and the corresponding entity or entities serve different roles. If you are indeed applying domain-driven design then your domain entities consist of not only data but behavior. By contrast, DTOs only carry data and serve as an adapter between your domain and WCF. All of this makes even more sense in the context of a hexagonal architecture also called ports and adapters as well as the onion architecture. Your domain is at the core and WCF is a port which exposes your domain externally. A DTO is part of how WCF functions and if you agree that it is a necessary evil your problem shifts from attempting to eliminate them to embracing them and instead focusing on how to facilitate the mapping between DTOs and domain objects. A popular solution is AutoMapper which reduces the amount of boiler plate mapping code you need to write. Aside from the drawbacks, DTOs also bring a lot of benefits. One is that they furnish a buffer between your domain entities and the outside world. This can be of great help in refactoring because you can keep your core domain very well encapsulated. Another benefit is that you can design your DTOs such that they fulfill requirements of the service consumer, requirements which may not always be in full alignment with the shape of your domain objects.
Personally, I don’t like using MessageContract as entities. Unfortunately, I have an existing WCF service that use MessageContract as entities – i.e. data is filled into the MessageContract directly in the data access layer. There is no translation layer involved.
I have an existing C# console application client using this service. Now, I have a new requirement. I need to add a new field in the entity. This is not needed by the client. The new field is only for the internal calculations in the service. I had to add a new property named “LDAPUserID” in the MessageContract which also act as a entity.
This may or may not break the client depending on whether the client support Lax Versioning. Refer Service Versioning.
It is easy to mistakenly believe that adding a new member will not break existing clients. If you are unsure that all clients can handle lax versioning, the recommendation is to use the strict versioning guidelines and treat data contracts as immutable.
With this experience, I believe it is not good to use MessageContract as entities.
Also, refer MSDN - Service Layer Guidelines
Design transformation objects that translate between business entities and data contracts.
References:
How do I serialize all properties of an NHibernate-mapped object?
Expose object from class library using WCF
Serialize subset of properties only
I have a WCF that uses a ADO.NET Entity Data Model to access SQL Server.
To insert a new row in a table with seven columns I'm using a WCF method.
I think send seven parameters it's too much, so I can use a struct or table's entity object.
What do you think? Do you recommend me to expose an entity object through WCF? Or I need to use a struct to avoid do that.
It depends on size / complexity of your application. Exposing entity is possible but it can cause some serialization problems when transporting whole object graph (entity with its relation). These problems are usually solved by marking entities with DataContract and DataMember attributes (used by default if you use EFv1 or default entity generation in EFv4 = no T4 templates).
The second approach you described is recommended if you want to follow clean architecture and good separation of concerns but it will make your application more complex (another layer of objects, conversions, etc.). Structures or classes created for data transportation are generally called DTOs (Data Transfer Objects).
Data Transfer Objects allow you transferring only necessary subset of data required for entity. If you for example have some infrastructural properties in the entity (like CreatedAt, CreatedBy) you will not want client to set these properties because it is responsibility of the service to set them. Because of that there is no need to allow client passing them. By not exposing these properties in the DTO you will make this clear.
My experience of using entities as Data Contracts is that you continually run into all kinds of hassle. Maintaining DTOs is not ideal, but gives you very fine grained control including the ability to change your DB schema without changing your contracts, and also control over the fields exposed by your service.
Automapper can really help you: http://automapper.codeplex.com/
We are taking a long, hard look at our (Java) web application patterns. In the past, we've suffered from an overly anaemic object model and overly procedural separation between controllers, services and DAOs, with simple value objects (basically just bags of data) travelling between them. We've used declarative (XML) managed ORM (Hibernate) for persistence. All entity management has taken place in DAOs.
In trying to move to a richer domain model, we find ourselves struggling with how best to design the persistence layer. I've spent a lot of time reading and thinking about Domain Driven Design patterns. However, I'd like some advice.
First, the things I'm more confident about:
We'll have "thin" controllers at the front that deal only with HTTP and HTML - processing forms, validation, UI logic.
We'll have a layer of stateless business logic services that implements common algorithms or logic, unaware of the UI, but very much aware of (and delegating to) the domain model.
We'll have a richer domain model which contains state, relationships, and logic inherent to the objects in that domain model.
The question comes around persistence. Previously, our services would be injected (via Spring) with DAOs, and would use DAO methods like find() and save() to perform persistence. However, a richer domain model would seem to imply that objects should know how to save and delete themselves, and perhaps that higher level services should know how to locate (query for) domain objects.
Here, a few questions and uncertainties arise:
Do we want to inject DAOs into domain objects, so that they can do "this.someDao.save(this)" in a save() method? This is a little awkward since domain objects are not singletons, so we'll need factories or post-construction setting of DAOs. When loading entities from a database, this gets messy. I know Spring AOP can be used for this, but I couldn't get it to work (using Play! framework, another line of experimentation) and it seems quite messy and magical.
Do we instead keep DAOs (repositories?) completely separate, on par with stateless business logic services? This can make some sense, but it means that if "save" or "delete" are inherent operations of a domain object, the domain object can't express those.
Do we just dispense with DAOs entirely and use JPA to let entities manage themselves.
Herein lies the next subtlety: It's quite convenient to map entities using JPA. The Play! framework gives us a nice entity base class, too, with operations like save() and delete(). However, this means that our domain model entities are quite closely tied to the database structure, and we are passing objects around with a large amount of persistence logic, perhaps all the way up to the view layer. If nothing else, this will make the domain model less re-usable in other contexts.
If we want to avoid this, then we'd need some kind of mapping DAO - either using simple JDBC (or at least Spring's JdbcTemplate), or using a parallel hierarchy of database entities and "business" entities, with DAOs forever copying information from one hierarchy to another.
What is the appropriate design choice here?
Martin
Your questions and doubts ring an interesting alarm here, I think you went a bit too far in your interpretation of a "rich domain model". Richness doesn't go as far as implying that persistence logic must be handled by the domain objects, in other words, no, they shouldn't know how to save and delete themselves (at least not explicitely, though Hibernate actually adds some persistence logic transparently). This is often referred to as persistence ignorance.
I suggest that you keep the existing DAO injection system (a nice thing to have for unit testing) and leave the persistence layer as is while trying to move some business logic to your entities where it's fit. A good starting point to do that is to identify Aggregates and establish your Aggregate Roots. They'll often contain more business logic than the other entities.
However, this is not to say domain objects should contain all logic (especially not logic needed by many other objects across the application, which often belongs in Services).
I am not a Java expert, but I use NHibernate in my .NET code so my experience should be directly translatable to the Java world.
When using ORM (like Hibernate you mentioned) to build Domain-Driven Design application, one of good (I won't say best) practices is to create so-called application services between the UI and the Domain. They are similar to stateless business objects you mentioned, but should contain almost no logic. They should look like this:
public void SayHello(int id, String helloString)
{
SomeDomainObject target = domainObjectRepository.findById(id); //This uses Hibernate to load the object.
target.sayHello(helloString); //There is a single domain object method invocation per application service method.
domainObjectRepository.Save(target); //This one is optional. Hibernate should already know that this object needs saving because it tracks changes.
}
Any changes to objects contained by DomainObject (also adding objects to collections) will be handled by Hibernate.
You will also need some kind of AOP to intercept application service method invocations and create Hibernate's session before the method executes and save changes after method finishes with no exceptions.
There is a really good sample how to do DDD in Java here. It is based on the sample problem from Eric Evans' 'Blue Book'. The application logic class sample code is here.