Yesterday I spent some time poking around the .NET Framework libraries using Reflector and I came across the Converter delegate. It’s signature looks like this…

1 public delegate TOutput Converter<TInput, TOutput>( TInput input );

I thought I might put together a contrived example on using this delegate. So here goes… Let’s pretend that I have an Employee Class that looks like this:

 1 public class Employee {
 2       public Employee( string firstName, string lastName, ILocation location ) {
 3           _firstName = firstName;
 4           _lastName = lastName;
 5           _location = location;
 6       }
 7 
 8       public string FirstName {
 9           get { return _firstName; }
10       }
11 
12       public string LastName {
13           get { return _lastName; }
14       }
15 
16       public ILocation Location {
17           get { return _location; }
18       }
19 
20       private readonly string _firstName;
21       private readonly string _lastName;
22       private readonly ILocation _location;
23   }

The ILocation interface looks like this.

1 public interface ILocation
2   {
3       string Address { get; }
4       string City { get; }
5       string Province { get; }
6   }

Now let’s say i want to be able to convert my Employee object to an Employee data transfer object that looks like this…

 1 public class EmployeeDto {
 2       public EmployeeDto( string firstName, string lastName, string address, string city, string province ) {
 3           _firstName = firstName;
 4           _lastName = lastName;
 5           _address = address;
 6           _city = city;
 7           _province = province;
 8       }
 9 
10       public string FirstName {
11           get { return _firstName; }
12       }
13 
14       public string LastName {
15           get { return _lastName; }
16       }
17 
18       public string Address {
19           get { return _address; }
20       }
21 
22       public string City {
23           get { return _city; }
24       }
25 
26       public string Province {
27           get { return _province; }
28       }
29 
30       private readonly string _firstName;
31       private readonly string _lastName;
32       private readonly string _address;
33       private readonly string _city;
34       private readonly string _province;
35   }

I could create a full blown EmployeeConverter type to do the conversion or I could leverage the Converter delegate. To do this I could create a DomainToDtoConverter type which can be re-used for other domain to dto type conversions.

 1 public class DomainToDtoConverter< TIn, TOut > {
 2       public DomainToDtoConverter( TIn toConvert ) {
 3           _toConvert = toConvert;
 4       }
 5 
 6       public TOut Convert( Converter< TIn, TOut > method ) {
 7           return method( _toConvert );
 8       }
 9 
10       private readonly TIn _toConvert;
11   }

Notice that the Convert method takes in a Converter delegate? Using this type alone the client of this type would have to define a method that matches the converter delegate signature to do the conversion. This also means that you could use pass in an anonymous delegate, but that may not be the wisest choice because it’s possible that this conversion may need to occur in multiple places in our application. So let’s encapsulate that in a factory.

1 public class ConverterDelegateFactory
2   {
3       public static Converter< Employee, EmployeeDto > EmployeeConverterMethod =
4           delegate( Employee employee ) {
5               return
6                   new EmployeeDto( employee.FirstName, employee.LastName, employee.Location.Address, employee.Location.City,
7                                    employee.Location.Province );
8           };
9   }

Clients of the DomainToDtoConverter can now pass in the factory delegate method like so…

1 Employee employee = new Employee( "mo", "khan", new Location( "620 8th ave sw", "Calgary", "Alberta" ) );
2   EmployeeDto dto =
3       new DomainToDtoConverter< Employee, EmployeeDto >( employee ).Convert(
4           ConverterDelegateFactory.EmployeeConverterMethod );

The DomainToDtoConverter type can now be re-used for converting different types. Yes I know this is probably not the greatest example but hopefully it helps.

Converter.zip (11.65 KB)

comments powered by Disqus