uncategorized

Object conversion

A while back JP posted about how he likes to use a different set of objects for transferring data to the UI layer (Screen Bound Dtos) than the ones that he has implemented in the domain model. This is my preferred way to manage data flow as well. I find that it allows me to push data to the UI in only the context that is required for the one screen that I am working with at the time.

As part of a couple of discussions I had last week, I showed the implementation that I used on my last big project and which now has become the standard starting point for anything I work with. If you don’t want to read this any further I’ll tell you now that the implementation uses an ITranslate<From, To> interface that is applied to a base class (BaseTranslate<From, To>) which then is inherited by any class that needs to offer translation capability. You can download the source from here. Note that the source doesn’t include the assemblies for the Castle Windsor container that is used in the code.

What I was originally trying to solve with this translation code was a the existence of code that called for translation in the following way

1
2
Client client = ConvertToDomain.Instance.ConvertClientDto(clientDto); 
Address address = ConverToDomain.Instance.ConvertAddressDto(addressDto);

The main problem that I was trying to solve was that all conversions were implemented in one of two classes (one for Domain to Dto, the other for Dto to Domain) each which had around 10,000 lines of code. I wanted to have the translation code moved out into separate classes so that we had more adherence to the Single Responsibility Principle as well as increasing the testability of each one of the translations.

What I came up with was an interface that I called ITranslate that we could implement on any class that contained translation code. The interface looks like this

1
2
3
4
5
public interface ITranslate<From, To> 
{
To For(From from);
IEnumerable<To> For(IEnumerable<From> fromList);
}

What we get is the ability from every translation class to convert objects one at a time or many at a time. When I first implemented this I had no need for the conversion of many objects at once. In my implementations of this since I have added the “many” translation and in doing so I noted that the “many” translation almost always looked exactly the same. It was a foreach loop over the fromList and in that loop the single translation was called and yield returned. To get rid of this code I’m now creating a BaseTranslate class that looks like this

1
2
3
4
5
6
7
8
9
10
11
public abstract class BaseTranslate<From, To>:ITranslate<From, To> 
{
public abstract To For(From from);
public IEnumerable<To> For(IEnumerable<From> fromList)
{
foreach (From from in fromList)
{
yield return For(from);
}
}
}

Now my translation classes implement the BaseTranslate class instead of the ITranslate interface. My concrete implementations now only contain code that is specific to that one scenario. Here’s an example of a concrete implementation for Client and ListClientDto objects

1
2
3
4
5
6
7
8
9
10
11
12
public class ClientToDtoTranslator:BaseTranslate<Client, ListClientDto> 
{
public override ListClientDto For(Client from)
{
ListClientDto listClientDto = new ListClientDto();
listClientDto.Id = from.Id;
listClientDto.Name = from.Name;
listClientDto.City = from.BillingAddress.City;
listClientDto.Province = from.BillingAddress.Province;
return listClientDto;
}
}

When I initially was getting a guy at work to do all of this refactoring (I think there was something like 200 conversions stuck in those 2 original classes) we decided to use a factory to dispense the appropriate translator depending on the To and From types that were passed into the factory object. The factory had all instances of all the concretions stored in a Dictionary<From, Dictionary<To, ITranslate<From, To>>> structure. The guy writing this cussed me up and down (Hey Ted!) because of the overhead that we had to manage in the factory. Eventually we found that it was just too much as we had translators that required other translators inside of them. If things weren’t ordered properly in the constructor of the factory, converters would just throw null reference errors all over the place. Ted managed to figure out how to over come this, but in the end it wasn’t pretty and every time I think about it I feel dirty.

Since then I’ve decided that using an IoC container is the way to go. As you’ll see in the sample code, I’m using Castle Windsor and it’s given me a very clean implementation. For this sample I’ve decided to create the instance of the Windsor container in a singleton. If I were doing this in a real project I’d probably put it somewhere else, but for simplicities sake this is what I did here. What you end up with is a Windsor config file that has something that looks like this in it (this is the entry for a ClientToClientDtoTranslator)

1
<component id="ClientToClientDtoTranslator" service="IglooCoder.Spike.Translations.Core.Translators.ITranslate`2[[IglooCoder.Spike.Translations.Core.Model.Client, IglooCoder.Spike.Translations.Core],[IglooCoder.Spike.Translations.Core.Dtos.ListClientDto, IglooCoder.Spike.Translations.Core]], IglooCoder.Spike.Translations.Core" type="IglooCoder.Spike.Translations.Core.Translators.ClientToDtoTranslator, IglooCoder.Spike.Translations.Core" />

It’s ugly, there’s no doubt about it. The nastiness comes from the fact that I’m going to be calling the container looking for an object that implements ITranslate<Client, ClientDto> and the notation for generics is just gross. Regardless, I will need to have one of these entries in my Windsor configuration file for each of the concrete implementations that I have in my application. My only complaint about this is that you loose a little bit of refactoring power because you now have the class and interface names in strings.

What I was striving for was a minimalist code implementation that also exposed a clean API for developers to work with. Below is the one and two line calls that the developer can work with. I prefer the one line implementation, but it’s developer preference I think.

1
2
3
ListClientDto dto = Container.Instance().ResolveFor<ITranslate<Client, ListClientDto>>().For(client); 
ITranslate<Client, ListClientDto> translator = Container.Instance().ResolveFor<ITranslate<Client, ListClientDto>>();
ListClientDto dto2 = translator.For(client);

That one line hits the IoC container which resolves the type to return and then it uses the For(…) method to do the final translation.

I’m not sure if this will work in a lot of scenarios, but the four or five times I’ve needed to do something like this it has worked quite well.