2

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?

Michał Powaga
  • 22,561
  • 8
  • 51
  • 62
noir
  • 566
  • 2
  • 5
  • 19

2 Answers2

4

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());
Krzysztof Kozmic
  • 27,267
  • 12
  • 73
  • 115
  • 1
    Thank you so much, I was reading the breaking changes but I did not find the one mentioning this. I am a beginner with Castle Windsor project so I may not even know what change I am looking for. – noir Dec 18 '11 at 11:44
0

For me this code worked :

public class AutoMapperInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            // Register all mapper profiles
            container.Register(
                Classes.FromAssemblyInThisApplication(GetType().Assembly)
                .BasedOn<Profile>().WithServiceBase());
                
            // Register IConfigurationProvider with all registered profiles
            container.Register(Component.For<IConfigurationProvider>().UsingFactoryMethod(kernel =>
            {
                return new MapperConfiguration(configuration =>
                {
                    kernel.ResolveAll<Profile>().ToList().ForEach(configuration.AddProfile);
                });
            }).LifestyleSingleton());
            
            // Register IMapper with registered IConfigurationProvider
            container.Register(
                Component.For<IMapper>().UsingFactoryMethod(kernel =>
                    new Mapper(kernel.Resolve<IConfigurationProvider>(), kernel.Resolve)));
        }
}
Simple Code
  • 2,354
  • 2
  • 27
  • 56