Los Techies : Blogs about software and anything tech!

AutoMapper feature: interfaces and dynamic mapping


In this post, I’ll highlight two features new in the 0.3 release: mapping to interfaces and dynamic mapping.  Both of these come up in rather interesting scenarios.

Mapping to interface destinations

In some messaging scenarios, the message itself is not a DTO type, but rather an interface.  In these cases, it’s rather annoying to create a derived type just for every interface-based message in your system.  Instead, we can use AutoMapper to do the work for us.  Suppose we have these source types:

public class OrderForm
{
    public Customer Customer { get; set; }
}

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

These can be from a complex domain model, external system, or business objects.  We now need to interface with some external system, but they’ve defined their message contracts as interfaces.  It’s not completely out of the question, but I run into this from time to time.  It might require some message like:

public interface ICreateOrderMessage
{
    string CustomerName { get; set; }
}

In this case, the destination type is an interface, and its member is a flattened version of our domain model.  Here’s our mapping code:

Mapper.CreateMap<OrderForm, ICreateOrderMessage>();

Mapper.AssertConfigurationIsValid();

var order = new OrderForm
    {
        Customer = new Customer {Name = "Bob Smith"}
    };

var message = Mapper.Map<OrderForm, ICreateOrderMessage>(order);

message.CustomerName.ShouldEqual("Bob Smith");

I create a type map from the source type (OrderForm) to the destination interface type.  An implementation ICreateOrderMessage doesn’t exist anywhere in our system.  I create the order form, and map to the message with the Mapper.Map call.  At runtime, AutoMapper creates a dynamic proxy type for ICreateOrderMessage, using the default property behavior for getters and setters.  Underneath the covers, I used LinFu to create the proxy type.  Using this feature does not require any additional references, however, as the LinFu assembly is merged into the AutoMapper assembly.

Dynamic mapping

In most mapping scenarios, we know the type we’re mapping to at compile time.  In some cases, the source type isn’t known until runtime, especially in scenarios where I’m using dynamic types or in extensibility scenarios.  To support these scenarios, but still preserve the safety of configuration validation, AutoMapper 0.3 includes a way to dynamically map from a source to a destination type.  No configuration is needed, just one call to AutoMapper.  I’ll still try to map to the interface destination:

public interface ICreateOrderMessage
{
    string CustomerName { get; set; }
}

And instead of creating a OrderForm in the previous example, I’ll use a dynamic type:

var order = new {CustomerName = "Bob Smith"};

var message = Mapper.DynamicMap<ICreateOrderMessage>(order);

message.CustomerName.ShouldEqual("Bob Smith");

The DynamicMap call creates a configuration for the type of the source object passed in to the destination type specified.  If the two types have already been mapped, AutoMapper skips this step (as I can call DynamicMap multiple times for this example).  To be safe, AutoMapper will validate the configuration for a dynamic map the first time executed, as it tends to give better messages than a mapping exception.

With DynamicMap, you don’t have the luxury of configuring the mapping, but at this point, you’ve also lost the benefits of a single AssertConfigurationIsValid call.  In the DynamicMap side, I could lower the bar quite a bit and not do any mapping validation, but I’d rather not as its intended use is a very specific scenario.  The ideal case is to configure your mappings up front, for much better testability.

Kick It on DotNetKicks.com
Posted Apr 14 2009, 10:39 PM by bogardj
Filed under:

Comments

DotNetShoutout wrote AutoMapper feature: interfaces and dynamic mapping - Jimmy Bogard
on 04-15-2009 7:56 AM

Thank you for submitting this cool story - Trackback from DotNetShoutout

Arjan`s World » LINKBLOG for April 15, 2009 wrote Arjan`s World &raquo; LINKBLOG for April 15, 2009
on 04-15-2009 2:46 PM

Pingback from  Arjan`s World    » LINKBLOG for April 15, 2009

Pavel Korotkov wrote re: AutoMapper feature: interfaces and dynamic mapping
on 02-15-2010 11:58 AM

Hi, Bogardj

Recently I started to playing with AutoMapper and got very enthusiastic about it. It's really powerful and elegant, I like it.

The question (might be trivial) is that how I can create a dynamic proxy for the given interface

public interface ITest

{

   Int32 Id { get; }

   String Name { get; }

}

If I attribute the properties with set accessors everything works fine with lines

var tc = new { Id = 1, Name = "Bob" };

var ctc = Mapper.DynamicMap<ITest>(tc);

var id = ctc.Id;

When I have only get accessors an exception is thrown: "KeyNotFoundException. The given key was not present in the dictionary." Does my setup need some tuning?

Thanks, PK

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

Enter the numbers above:
Copyright Los Techies 2008, 2009. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems