WCF DataContracts and underlying data structures - wcf

I am wondering what makes sense in relation to what objects to expose through a WCF service - should I add WCF Serialization specifications to my business entities or should I implement a converter that maps my business entities to the DataContracts that I want to expose through my WCF service?
Right now I have entities on different levels: DataAccess, Business and Contract. I have converters in place that can map entities from DataAccess to Business and from Business to Contract and vice versa. Implementing and Maintaining those is time consuming and pretty tedious. What are best practices in relation to this?
If I were using an OR/M such as NHibernate or Entity Framework should I be exposing the entities from the ORM directly or should I abstract them the same way I am doing now?

In general, I think from a best practices standpoint, you should not expose the structure of your business objects as data contracts, but rather define "data contract-specific" classes and convert Business to Contract. It may require extra work, but from a separation of concerns and protection from change standpoint the extra work is probably worth it.
The Microsoft patterns & practices "Service Factory Modeling Edition" implements this, and also provides tooling to auto-generate Business <=> Contract converter classes -- it's an excellent VS add-in, and also represents Microsoft's best practices for WCF.

I typically don't expose my business/data entities across the wire since I like to adhere to the single responsibility principle (srp). To explain, the data entities were created to map to the underlying relational (db) model. So the only reason they should "change", is because of a change to the relational model, that's it.
The moment you expose such entities so they can cross the wire, then they're serving two purposes. It may seem like overkill, but it keeps things cleaner and transparent...which yields for a simpler design.

Just to add to the above answers:
The object that the webservice exposes is called the Data Transfer Object (DTO). Having a DTO to map your Business Entity object (BEO) is good because of the separation it provides between your webservice and the actual implementation/logic that lies behind the web-service.
Finally, here is how you can decorate the DTO so that when it is exposed by the WSDL the names reflect the actual objects it represent (instead of objectNameDTO or something ugly like that).
//Business Entity
class Person
{
public string Name{ get; set; }
public int Age{ get; set; }
}
//Data transfer object
[DataContract(Name="Person")] //<-- this is what makes the WSDL look nice and clean
class PersonDTO
{
[DataMember(Name = "Name", Order = 0)]
public string Name{ get; set; }
[DataMember(Name = "Age", Order = 1)]
public int Age{ get; set; }
}

Something to also consider, I agree with the separation but it usually winds up leading to "Translators" or some such code to copy the data from the DTO to the Business Entity. This is where a library like AutoMapper (http://automapper.org/) comes in REAL handy and does away with the need to write the translation layer.

Related

How to use and create DTOs is OOP world?

What is the right way to create DTOs from business objects?
Who should be responsible for creating them? BO/DTO itself from BO/some static factory?
Where should they reside in code if I have, f.e. some core library and a specific service API library that I need DTO for? In core library next to BO(which seems incorrect)/in specific library?
If I have encapsulated fields in my BO how do DTO grab them? (obviously in case when BO is not responsible for creating DTOs)
As an example assume that I have some Person BO like this:
class Person
{
private int age;
public bool isBigEnough => age > 10;
}
I want age to be an internal state of Person but still I need to communicate my BO to some api. Or having private field in my class that I want to send somewhere already means that it should be public?
Are there any general considerations of how to use DTOs alongside business classes with encapsulated data?
___ Update:
In addition to approaches that #Alexey Groshev mentioned I came accross another one: we separate data of our BO class into some Data class with public accessors. BO wraps this data with its api(probably using composition) and when needed it can return its state as Data class as clone. So dto converter will be able to access Domain object's state but won't be able to modify it(since it will be just a copy).
There're multiple options available, but it would be difficult to recommend anything, because I don't know the details about your project/product. Anyway I'll name a few.
You can use AutoMapper to map BOs to DTOs and vise versa. I personally dislike this approach, because it's quite difficult (but possible) to keep it under control in medium/large sized projects. People don't usually bother to configure mappings properly and just expose internal state of their objects. For example, your isBigEnough would disappear and age would become public. Another potential risk is that people can map DTOs to/from EF/Hibernate objects. You can find some articles which explain why it's considered to be a bad practice.
As you suggested, a BO can create DTO by itself, but how would you implement this approach? You can add methods or factory methods to your entities, e.g. public PersonDto ToDto(). Or you can add an interface, e.g. public interface IDtoConvertable<T> { T ToDto(); }, and choose which entity or aggregate root will implement it. Your Person class would look like this class Person : IDtoConvertable<PersonDto> {... public PersonDto ToDto() {...} }. In both cases DTO namespace/assembly must to accessible by entities which sometimes can be a problem, but usually it's not a biggie. (Make sure that DTOs cannot access entities which is much worse.)
(C#) Another option is to return a delegate which creates DTO. I decided to separate it from (2), because entity doesn't really create DTO by itself, but rather exposes a functionality which creates DTO. So, you could have something like this public Func<PersonDto> ToDto() {...}. You might want to have an interface as in (2), but you get the idea, don't you? Do I like this approach? No, because it makes code unreadable.
As you see, there are more questions than answers. I'd recommend you to make a few experiments and check what works for you (your project) and what doesn't.
I think the answer to question 5 will address the other questions too.
Are there any general considerations of how to use DTOs alongside business classes with encapsulated data?
Remember, a DTO is solely to transfer data. Do not concern yourself with implementing any kind of rules in the DTO. All it is used for is to move data from one subsystem to another (NOT between classes of the same subsystem). How that data is used in the destination system is out of your control -- although as the God programmer you inherently know how it is going to be used, DO NOT let that knowledge influence your design -- and therefore there should be no assumptions expressed as behaviour or knowledge accessors -- so, no isBigEnough.

Serializing Composed Objects

I see Composite Oriented Programming and DCI as interesting techniques
to use within a rest framework, but have run into an issue.
Is it possible to serialize a mixin object and get all it's
properties? For example:
public class IHasOwner
{
string owner();
}
public class HasEngine
{
string engine();
}
Let's say we make a CarComposite object with the two classes above as
mixins. Could I deserialize this CarComposite class to get the
following xml?:
<CarComposite>
<owner></owner>
<engine></engine>
</CarComposite>
I'm curious to how this is handled in general, but with close
attention to .NET, since you canot deserialize Interfaces.
I find that a view- or resource-model is often called for in RESTful services. I.e. a set of dumb data types tailored for the way you want to expose the resource. These do not need to match domain objects. You do need to be able map between the two though. The dumb resource-model is "easy" to serialize.
For the mapping between domain and service model objects AutoMapper can be quite useful.

When does an object qualify as a DTO?

DTO (Data Transfer Objects) are objects used to transfer information between multiple subsystems of an application, often separated by either a network or a process boundary. This is my understanding.
However, from Java perspective, do the subsystems/modules have to be on different JVM instances for the objects they use between them to qualify as DTOs? (I believe that a significant demarcation in architecture in terms of modularity and functionality between the subsystems would be sufficient.) What say?
Also, considering the objects exchanged by multiple modules in the SAME layer/tier of an architecture, don't these objects qualify as DTOs? Is a tier separation mandatory?
Thanks in advance.
Regards,
Nagendra U M
Because transferring objects between tiers requires some kind of serialization it is considered a DTO. Transferring objects between layers is generally done through the use of domain entities thus not requiring serialization.
So your DTOs generally do not have behavior only properties to hold data.
A little note: DTOs are often mistaken for anemic objects when you have entities with no behavior, only data. Or poltergeist objects when objects are only used to transport data in and out of methods or classes and then disappear.
As an example sometimes your data persistence mechanism requires you to implement or inherit interfaces or classes that you do not want to couple into your domain layer, so you create objects that inherit or implement the interface/class and transfer data to those classes for persistence.
class Person{
public string Name {get;set;}
public int Age {get;set;}
public void Validate(){}
public void DoSomething(){}
}
public class PersonDTO : TableServiceContext
{
public const string ContactTableName = "PersonTable"
public string Name {get;set;}
public int Age {get;set;}
}
And you would generaly have a class to assemble and disassemble these objects.

WCF and Fluent NHibernate: how can i keep "clean" classes?

i'm investigating Nhibernate, jquery and WCF at the same time for a in-house project, and i was wondering why i couldn't have "clean" data classes.
From what i've read, a very good point in the nhibernate world is that my business class won't be linked to the framework.
I won't have
<SaveInTable("Thingie")> _
Public Class Thingie
<ColumnName("ThingieId")> _
Public Property Id as Integer
' accessors
End Class
but rather something like
Public Class Thingie
Public Property Id as Integer
' etc
And then
Public Class ThingieMapping
Inherits ClassMap(Of Thingie)
' etc, omitted for brevity's sake
What i don't understand is that if i want to list Thingies in a web page with jQuery, and if i want to use WCF webservices with jquery (it looks like the current trend from what i've seen on various tutorials), i find myself having to add DataContract and DataMember attributes to my Thingie class.
On the other hand, the classic ASMX webservices won't bother me and let me retrieve the Thingie class without worrying about adding attributes.
I have the feeling that i'm missing part of the picture here; it seems logical to try keeping the Thingie class mostly independent, but i haven't found examples so far.
So, do i have to abandon all hopes and stick to the classic webservices, or is there a way to have my WCF cake and eat it too?
I suggest you use DTOs to send over the wire - then you can decorate the DTOs with the necessary attributes.
This means, of course, that you must somehow map your domain classes to the DTOs and vice versa. If the mapping is trivial (+some other cases that satisfies some conventions), you can use AutoMapper for that.
Using DTOs has several benefits, the best being that you have a clear seperation of concerns - your NHibernate-mapped domain model is about modeling stuff in your domain, and your DTOs are for sending data over the wire. Then, if one changes, the other doesn't necessarily need to change as well.

WCF Contracts from Entity Framework?

I've been coming up with a lot of dead ends on this question. Supposedly, .NET 3.5 SP1 has Support for ADO.NET Entity Framework entities in WCF contracts. But when I look for solid info on it I'm not getting a lot of answers. I found this one snippet on an MSDN thread. Does anyone have any experience with this? What happened to the [DataContract]? Is this all there is to it? Why is there so little material on this?
This the answer from Tim Mallalieu in Microsoft.
Entity Types that are generated in the Entity Framework are, by default Data Contracts.
If I were to create a simple model in the Entity Designer like the following:
The cart Entity Type is by default a DataContract with all properties annotated as data members. We can then use this in a WCF service as follows:
[ServiceContract]
public interface IService1
{
[OperationContract]
Cart[] AllCarts();
}
public class Service1 : IService1
{
public Cart[] AllCarts()
{
using (MSPetShop4Entities context = new MSPetShop4Entities())
{
var carts = from c in context.Carts select c;
return carts.ToArray();
}
}
}
As the Entities are DataContracts you can now roll your services as you see fit and send these across the wire.
I recommend that you not return Entities directly. Unfortunately, Microsoft chose to include implementation-specific data as part of the DataContract for entities. This will not interoperate with other platforms, and is the sort of thing that might fail to interoperate even between .NET versions.
Instead, I recommend you follow the Data Transfer Object pattern and just return POCO classes that are copies of the data in the entities, with no behavior. You can return List of such classes to represent a table, etc.
The "sharing interfaces and not type" tenet presupposes that you don't own both ends of the wire and/or you're writing a public-facing web service. WCF can be used (and is used) in contexts where this is decidedly not the case. Many enterprise n-tier architectures have a WCF-fronted application tier to facilitate load-balancing among other things. In these cases it is perfectly valid to share type and, in fact, is desired.
You could go the easy way and use ADO.NET Data Services.
Some more detail in response to comments:
There are several problems with the classes generated by EF. I'm looking now at an AdventureWorks example with SalesOrderHeader and SalesOrderDetail. The SalesOrderDetail entity has both "SalesOrderHeader" and "SalesOrderHeaderReference" properties, both marked as DataMembers. This looks like a bug, since the "SalesOrderHeader" property is also marked [XmlIgnore] and [SoapIgnore].
Also, consider whether you want to serialize the link back to the parent SalesOrderHeader in the first place. Besides, what exactly should be serialized? SOAP doesn't support references in an interoperable manner.
Finally, the base classes of the entities are also data contracts. Yet they have nothing to do with the data you are returning - they are purely an implementation artifact.
In short, Microsoft screwed up on this one. They didn't think it through.
About ways to generate the DTO classes, I suggest looking into various code generation tools, like CodeSmith. You can write code to do this yourself; I did so in my previous position. The nice thing about generating the DTO is that you also get to generate the methods to translate to and from the DTO.
As to overhead, the overhead of moving some data around in memory is nothing compared to the amount of time it's going to take to send the data over a network!