Search code examples
castle-windsorioc-containerautomapperautomapper-2

Castle Windsor does not resolve AutoMapper profiles after update


Everything was working fine until I updated with NuGet the references for CastleWinsor and AutoMapper to their latest versions: Castle.Windsor.3.0.0.4001 and AutoMapper.2.0.0.

I have a list of AutoMapper profiles in the same assembly as the AutoMapperInstaller : IWindsorInstaller. They are in diferent namespaces, but this should not matter, right?

Here is a profile example:

namespace FieldService.Web.Mappings
{
 public class RoleMappings : Profile
 {
    protected override void Configure()
    {
        AutoMapper.Mapper.CreateMap<RoleModel, Role>()
            .ConstructUsing((role) => new Role() { Permissions = new List<Permission>() })
            .ForMember(m => m.Permissions, o => o.MapFrom(src => src.Permissions.Where(p => p.Selected == true)));
    }
 }
}

Here is the AutoMapperInstaller

namespace FieldService.Web.Infrastructure.IOC
{
 public class AutoMapperInstaller : IWindsorInstaller
 {
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        Mapper.Initialize(x => x.ConstructServicesUsing(container.Resolve));

        RegisterProfilesAndResolvers(container);
        RegisterMapperEngine(container);
    }

    private void RegisterMapperEngine(IWindsorContainer container)
    {
        container.Register(
            Component.For<IMappingEngine>().Instance(Mapper.Engine)
        );
    }

    private void RegisterProfilesAndResolvers(IWindsorContainer container)
    {
        // register value resolvers
        container.Register(AllTypes.FromAssembly(Assembly.GetExecutingAssembly()).BasedOn<IValueResolver>());

        // register profiles
        container.Register(AllTypes.FromThisAssembly().BasedOn<Profile>());
        var profiles = container.ResolveAll<Profile>();

        foreach (var profile in profiles)
            Mapper.AddProfile(profile);
    }
 }
}

In Global.asax I have the method BootstrapContainer which I call from Application_Start method:

private static readonly IWindsorContainer container = new WindsorContainer();

    public IWindsorContainer Container
    {
        get { return container; }
    }

    private static void BootstrapContainer()
    {
        container.Install(FromAssembly.This());
    }

The exception I get is: Trying to map xxx to yyyModel. Missing type map configuration or unsupported mapping. Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.

I debugged the installer and I think this line Container.Register(AllTypes.FromThisAssembly().BasedOn<Profile>()); is not working anymore.

If I try to resolve the profiles (next line) it returns 0 profiles.

I am not an expert with these two tools, and I am not sure this is the best method to initialize AutoMapper with Windsor but it worked until now.

Any idea why this is not working anymore?


Solution

  • This is a known and documented breaking change in Windsor (see breakingchanges.txt for details).

    In short, if you're resolving your profiles as Profile you need to register them as Profile.

    Container.Register(AllTypes.FromThisAssembly().BasedOn<Profile>().WithServiceBase());