The lowly DTO, a pattern described by Martin Fowler that enables you to reduce the number of API calls you make across a remote boundary; it allows this by grouping all the data in to a new data type and returning that instead. I have however found that this pattern can cause you to write a lot of code that is nothing more than property setting. The code provided in this post (here) allows you to automate the population of these DTOs saving you time, so you can get on with something more important like drinking coffee.
First of all grab yourself a copy of the source code. A general overview of the process is; you specify — using attributes — the mappings between your business objects and your data transfer objects. These attributes can describe simple properties, complex properties and collections. After that is done, throw the object at the converter and Bob’s your uncle!
There are two attributes DTOSimpleMapper and DTOCollectionMapper; the basic signature of the attributes is shown below.
[DTOSimpleMapper(params string[] fields)] [DTOCollectionMapper(Type ofType, string fromField)]
[DTOSimpleMapper("FromProperty.Child.Identifier")]
public int ConvertedProperty;
The ‘fields’ and ‘fromField’ parameters describe the property on the origin object that is to be converted. The destination for the conversion is always the property the attribute is decorating. The fields are represented as a string where the field is a child property the ‘.’ notation can be used to indicate this. I.e. “Parent.Child.Child”.
The params string[] parameters on both attributes can be used to describe more complex conversions, when the converting types have multiple properties the conversion can be described by passing in an array of strings which define the from and to properties. I.e:
[DTOSimpleMapper("Prop1.Prop2=Identifier", "Prop2.Prop1=Name")]
The first parameter on the DTOCollectionMapper tells the converter what the destination array elements are:
[DTOCollectionMapper(typeof(string), "FromProperty"] public string[] ConvertedCollection;
The converter will work with any collection that implements IEnumerable. As with the simple mapper, the property name can describe more complex conversions. This is useful where you have a generic DTO that is used to describe many elements:
[DTOCollectionMapper(typeof(IdentifiedElement), "FromPoperty", "Identifier=Identifier", "Child.Name=Name")] public List Children;
Finally where the conversions are more complex the type for the property can describe its own conversion:
Public class RelatedChildDTO {
[DTOSimpleMapper("Identifier")] public int Identifier;
[DTOSimpleMapper("Name")] public string Name;
}
Public class ParentDTO {
[DTOSimpleMapper("Child")]
public RelatedChildDTO Child;
}
With the above example the converter will check the type of instance it is creating and use the attributes described on that type to perform the conversion.
Both of the attributes allow for Type conditional conversions as well, both are overloaded with a type property that is checked in the conversion process and only performed when the origin type is the same:
[DTOSimpleMapper(typeof(ConditionalBusinessObject), "FromProperty")] public string ConvertedProperty;
Now you have described the way objects are converted we are left with actual conversion, the library has a Converter class with a simple static method called Convert. This method takes an instance of an origin object and a type for the destination object.
BusinessObject bus = new BusinessObject(); // set business properties DTO dto = (DTO)Convertor.Convert(bus, typeof(DTO));
The result of this method call is that the DTO is created and populated using the attributes, the conversion is done!
Here is the source code, it contains test classes which should give you a better idea of how it all works, enjoy!