Category Archives: AutoMapper

AutoMapper Converters

When using AutoMapper, it may be that we’re using types which map easily to one another, for example if the objects being mapped have the same type for a property or the type can be converted using the standard type convertes, but what happens when things get a little more complex?

Suppose we have a type, such as

public class NameType
{
   public string Name { get; set;
}

and we want to map between a string and the NameType, for example

var nameType = Mapper.Map<string, NameType>("Hello World");

As you might have suspected, this will fail as AutoMapper has no way of understanding how to convert between a string and a NameType.

You’ll see an error like this


Missing type map configuration or unsupported mapping.

Mapping types:
String -> NameType
System.String -> AutoMapperTests.Tests.NameType

Destination path:
NameType

Source value:
Hello World

What we need to do is give AutoMapper a helping hand. One way is to supply a Func to handle the conversion, such as

Mapper.CreateMap<string, NameType>().
	ConvertUsing(v => new NameType { Name = v });

alternatively we can supply an ITypeConvert implementation, such as

public class NameConverter :
   ITypeConverter<string, NameType>
{
   public NameType Convert(ResolutionContext context)
   {
      return new NameType {Name = (string) context.SourceValue};
   }
}

and use in like this

Mapper.CreateMap<string, NameType>().
   ConvertUsing(new NameConverter());

AutoMapper Profiles

When creating mappings for AutoMapper we can easily end up with a mass of CreateMap methods in the format

Mapper.CreateMap<string, NameType>();
Mapper.CreateMap<NameType, string>();

An alternate way of partitioning the various map creation methods is using the AutoMapper Profile class.

Instead we can create profiles with as fine or coarse granularity as you like, here’s an example

public class NameTypeProfile : Profile
{
   protected override void Configure()
   {
      CreateMap<string, NameType>()
      CreateMap<NameType, string>();
   }
}

To register the profiles we need to then use

Mapper.AddProfile(new NameTypeProfile());

which can also become a little tedious, but there’s an alternative to this…

AutoAutoMapper Alternative

So instead of writing the code to add each profile we can use the AutoAutoMapper in the following way

AutoAutoMapper.AutoProfiler.RegisterProfiles();

this will find the profiles within the current assembly or those supplied as params arguments to the RegisterProfiles method for us. This way the profiles are registered for you.

Entity Framework & AutoMapper with navigational properties

I’ve got a webservice which uses EF to query SQL Server for data. The POCO’s for the three tables we’re interested in are listed below:

public class Plant
{
   public int Id { get; set; }

   public PlantType PlantType { get; set; }
   public LifeCycle LifeCycle { get; set; }

  // other properties
}

public class PlantType
{
   public int Id { get; set; }
   public string Name { get; set; }
}

public class LifeCycle
{
   public int Id { get; set; }
   public string Name { get; set; }
}

The issue is that when a new plant is added (or updated for that matter) using the AddPlant (or UpdatePlant) method we need to ensure EF references the LifeCycle and PlantType within its context. i.e. if we try to simply call something like

context.Plants.Add(newPlant);

then (and even though the LifeCycle and PlantType have an existing Id in the database) EF appears to create new PlantTypes and LifeCycles. Thus giving us multiple instances of the same LifeCycle or PlantType name. For the update method I’ve been using AutoMapper to map all the properties, which works well except for the navigational properties. The problem with EF occurs.

I tried several ways to solve this but kept hitting snags. For example we need to get the instance of the PlantType and LifeCycle from the EF context and assign these to the navigational properties to solve the issue of EF adding new PlantTypes etc. I wanted to achieve this in a nice way with AutoMapper. By default the way to create mappings in AutoMapper is with the static Mapper class which suggests the mappings should not change based upon the current data, so what we really need is to create mappings for a specific webservice method call.

To create an instance of the mapper and use it we can do the following (error checking etc. remove)

using (PlantsContext context = new PlantsContext())
{
   var configuration = new ConfigurationStore(
                     new TypeMapFactory(), MapperRegistry.AllMappers());
   var mapper = new MappingEngine(configuration);
   configuration.CreateMap<Plant, Plant>()
         .ForMember(p => p.Type, 
            c => c.MapFrom(pl => context.PlantTypes.FirstOrDefault(pt => pt.Id == pl.Type.Id)))
	 .ForMember(p => p.LifeCycle, 
            c => c.MapFrom(pl => context.LifeCycles.FirstOrDefault(lc => lc.Id == pl.LifeCycle.Id)));

   //... use the mapper.Map to map our data and then context.SaveChanges() 
}

So it can be seen that we can now interact with the instance of the context to find the PlantType and LifeCycle to map and we do not end up trying to create mappings on the static class.

First Impressions – AutoMapper

One of the projects I’m working on (at the time of writing this post) is a C# client which uses Java web services. When creating the proxies we end up with DTO objects which have a few issues, some are aesthetic others functional.

On the aesthetic from they do not adhere to the Pascal case naming convention and use arrays instead of C# Lists, on the functional side they ofcourse are lightweight DTO objects so contain no business logic or the other additional functionality which we’d want in our Domain objects.

So we have ended up with a mass of mapping factories and functionality that converts a DTO object to a Domain object and in some cases the reverse also (not all Domain’s need to be converted back to DTO’s). There’s absolutely nothing wrong with these factories and mapping mechanisms whatsoever, but I came across AutoMapper recently (although it looks like its been around for a long while – so I’m somewhat late to the party) and thought I’d try to use it on a set of similar scenarios.

I’ll start with a couple of simple DTO classes, PersonView and CountryView.

public class CountryView
{
   public string name { get; set; }
}

public class PersonView
{
   public string name { get; set; }
   public int age { get; set; }
   public CountryView country { get; set; }
   public PersonView[] children { get; set; }
}

to start with the domain objects are going to be just as simple as the DTO’s but conforming to our preference of Pascal case property names and IList’s instead of arrays. So the domains look like

public class Country
{
   public string Name { get; set; }
}

public class Person
{
   public string Name { get; set; }
   public int Age { get; set; }
   public Country Country { get; set; }
   public IList<Person> Children { get; set; }
}

Okay nothing very complicated or particularly useful in the real world, if we were trying to model a family tree, but it’s good enough for us to start playing with.

So the next question is obviously how we tell AutoMapper to associate the mapping of one type to the other. This is handled via the Mapper.CreateMap method. We need to tell the mapper how to map every object type that makes up the object tree.

Mapper.CreateMap<PersonView, Person>();
Mapper.CreateMap<CountryView, Country>();

Note: If we wanted to convert the Domain objects back to DTO we’d need Mapper.CreatMap entries with the generic parameters switched also.

Finally, we want to actually convert one type of data (in this instance the DTO) to another type of data (in this case the Domain object). To do this we simply use

PersonView dto = GetPerson();
Person domain = Mapper.Map<PersonView, Person>(dto);

I’ll leave the reader to create the GetPerson method and supply some test data. But upon successful completion of the Mapper.Map call the domain object should now have all the data copied from the DTO plus a List instead of an array.

So within AutoMapper it’s obviously matched the properties by a case insensitive comparison of the property names but what, I hear you ask, if the property names on PersonView did not match those in the domain object.

To solve this we simply add some information to the mapping declarations along the following lines (assuming the DTO object name property is now n, age is a etc.)

Mapper.CreateMap<PersonView, Person>().
   ForMember(d => d.Age, o => o.MapFrom(p => p.a)).
   ForMember(d => d.Name, o => o.MapFrom(p => p.n)).
   ForMember(d => d.Name, o => o.MapFrom(p => p.co)).
   ForMember(d => d.Name, o => o.MapFrom(p => p.ch));

Finally for this post (as it’s mean’t to be the first impressions of AutoMapper not a comprehensive user guide :)) is what if the DTO property names all end in a standard postfix, for example nameField, ageField etc. Maybe the naming convention from the guys developing the web service uses the xxxField format and we’d prefer to not use the same. We wouldn’t really want to have to create the ForMember mappings for every field if we could help it. Instead we could use

Mapper.Initialize(c => c.RecognizePostfixes("Field"));

Note: the solution above is global, so would affect all mappings, but essentially now can handle exact case insensitive matches as well as insensitive matches with the postfix “Field”.