I have been using AutoMapper for some time now. I have a profile setup like so:
public class ViewModelAutoMapperConfiguration : Profile
{
protected override string ProfileName
{
get { return "ViewModel"; }
}
protected override void Configure()
{
AddFormatter<HtmlEncoderFormatter>();
CreateMap<IUser, UserViewModel>();
}
}
I add this to the mapper using the following call:
Mapper.Initialize(x => x.AddProfile<ViewModelAutoMapperConfiguration>());
However, I now want to pass a dependency into the ViewModelAutoMapperConfiguration
constructor using IoC. I am using Autofac. I have been reading through the article here: http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/05/11/automapper-and-ioc.aspx but I can't see how this would work with Profiles.
Any ideas?
Thanks
Well, I found a way of doing it by using an overload of AddProfile
. There is an overload that takes an instance of a profile, so I can resolve the instance before passing it into the AddProfile
method.
A customer of mine was wondering the same thing as DownChapel and his answer triggered me in writing some sample application.
What I've done is the following.
First retrieve all Profile
types from the asseblies and register them in the IoC container (I'm using Autofac).
var loadedProfiles = RetrieveProfiles();
containerBuilder.RegisterTypes(loadedProfiles.ToArray());
While registering the AutoMapper configuration I'm resolving all of the Profile
types and resolve an instance from them.
private static void RegisterAutoMapper(IContainer container, IEnumerable<Type> loadedProfiles)
{
AutoMapper.Mapper.Initialize(cfg =>
{
cfg.ConstructServicesUsing(container.Resolve);
foreach (var profile in loadedProfiles)
{
var resolvedProfile = container.Resolve(profile) as Profile;
cfg.AddProfile(resolvedProfile);
}
});
}
This way your IoC-framework (Autofac) will resolve all dependencies of the Profile
, so it can have dependencies.
public class MyProfile : Profile
{
public MyProfile(IConvertor convertor)
{
CreateMap<Model, ViewModel>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Identifier))
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => convertor.Execute(src.SomeText)))
;
}
}
The complete sample application can be found on GitHub, but most of the important code is shared over here.