Registering AutoMapper Profiles with Castle Windsor

Hackered
Thursday, June 4, 2015
by Sean McAlinden

For many years now, AutoMapper and Castle Windsor have both been steadfast libraries within my development arsenal.

I have also been re-using the same small number of classes for years to register my mapping files within the Castle Windsor container.

A little bit on AutoMapper Profiles

AutoMapper can be used and configured in a number of ways, I mainly create classes derived from AutoMapper's Profile class.

For example:

public class DomainToEntityMappingProfile : Profile
{
    public override string ProfileName
    {
        get { return "DomainToEntityMappingProfile"; }
    } 

    protected override void Configure()
    {
        Mapper.CreateMap<MyDomainEntity, MyViewModel>();
        Mapper.CreateMap<MyDomainEntity2, MyViewModel2>();
        base.Configure();
    }
}

As you can see the mapping code is nicely encapsulated in this class.

Profiles can be created to demarcate slices of your domain or however else makes sense to your application.

Initializing AutoMapper Profiles

Initializing a profile manually in code can be very simple and certainly a good choice if you only have one or two profiles.

The following is an example of initializing our above profile:

Mapper.Initialize(config =>
{
    config.AddProfile(new DomainToEntityMappingProfile());
});

Typically however, it is better to keep your classes small so inevitably multiple Profile classes will likely be added over time.

As new Profile classes are created, it would be much better if they were automatically initialized, this is where Castle Windsor comes in really handy.

Multiple Profile Registration with the AutoMapperInitializer class

public static class AutoMapperInitializer
{
    public static void Initialize(IEnumerable<Profile> profiles)
    {
        Mapper.Initialize(config => AddProfiles(config, profiles));
    }

    private static void AddProfiles(IConfiguration configuration, IEnumerable<Profile> profiles)
    {
        profiles.ToList().ForEach(configuration.AddProfile);
    }
}

Now the class will initialize multipe profiles, we just need a nice automated way to find them, this is bread and butter for Castle Windsor.

Find all profiles using Castle Windsor

public static class AutoMapperConfiguration
{
    public static void RegisterProfiles(IWindsorContainer windsorContainer)
    {
        windsorContainer.Register(
            Types.FromAssemblyInThisApplication()
                .BasedOn<Profile>()
                .WithService.Base()
                .Configure(c => c.Named(c.Implementation.FullName))
                .LifestyleTransient());

        var profiles = windsorContainer.ResolveAll<Profile>();

        if (profiles.Length > 0)
        {
            AutoMapperInitializer.Initialize(profiles);
        }
    }
}

Nice, now this is in place we just need to call this on application startup and we're there.

Global.asax - Lets hook this up

Add the following to your Application_Start() method in the Global.asax class:

var container = new WindsorContainer();
AutoMapperConfiguration.RegisterProfiles(container);

There you have it, all profiles within the application will now be automatically registered and initialized.

Using Automapper with the registered AutoMapper Profiles

Basically, you can use AutoMapper as you would normally now, just your create map statements are nicely encapsulated and discovered automatically.

var item = Mapper.Map<SomeType>(someObject);

I hope this was useful, I've certainly been using this code for years now and it has done well for me so far.

C#