温莎城堡更新后无法解析 AutoMapper 配置文件

发布于 2024-12-21 13:34:12 字数 2750 浏览 2 评论 0原文

一切都工作正常,直到我使用 NuGet 将 CastleWinsor 和 AutoMapper 的引用更新到最新版本:Castle.Windsor.3.0.0.4001AutoMapper.2.0.0

我在与 AutoMapperInstaller : IWindsorInstaller 相同的程序集中有一个 AutoMapper 配置文件列表。它们位于不同的命名空间中,但这应该不重要,对吧?

这是一个配置文件示例:

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)));
    }
 }
}

这是 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);
    }
 }
}

Global.asax 中,我有从 Application_Start 调用的方法 BootstrapContainer code> 方法:

private static readonly IWindsorContainer container = new WindsorContainer();

    public IWindsorContainer Container
    {
        get { return container; }
    }

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

我得到的异常是: 尝试将 xxx 映射到 yyyModel。缺少类型映射配置或映射不受支持。抛出了“AutoMapper.AutoMapperMappingException”类型的异常。

我调试了安装程序,我认为这一行 Container.Register(AllTypes.FromThisAssembly().BasedOn()); 是不再工作了。

如果我尝试解析配置文件(下一行),它会返回 0 个配置文件。

我不是这两个工具的专家,我不确定这是使用 Windsor 初始化 AutoMapper 的最佳方法,但它到目前为止一直有效。

知道为什么这不再起作用了吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

狠疯拽 2024-12-28 13:34:12

这是 Windsor 中已知且已记录的重大更改(有关详细信息,请参阅 breakingchanges.txt)。

简而言之,如果您将配置文件解析为 Profile,则需要将它们注册为 Profile

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

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());
橘香 2024-12-28 13:34:12

对我来说这段代码有效:

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)));
        }
}

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)));
        }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文