如何配置Automapper以便与Ninject 2.0一起注入?

4
2个回答

5

非常简单,只需加载此模块:

public class AutoMapperModule : NinjectModule
{
    public override void Load()
    {
        Bind<ITypeMapFactory>().To<TypeMapFactory>();
        foreach (var mapper in MapperRegistry.AllMappers())
            Bind<IObjectMapper>().ToConstant(mapper);
        Bind<Configuration>().ToSelf().InSingletonScope()
            .WithConstructorArgument("mappers",
                ctx => ctx.Kernel.GetAll<IObjectMapper>());
        Bind<IConfiguration>().ToMethod(ctx => ctx.Kernel.Get<Configuration>());
        Bind<IConfigurationProvider>().ToMethod(ctx => 
            ctx.Kernel.Get<Configuration>());
        Bind<IMappingEngine>().To<MappingEngine>();
    }
}

关于这个问题需要注意以下几点:
  • Configuration的构造函数中,不仅只提供MapperRegistry.AllMappers参数,实际上会绑定每个单独的IObjectMapper,然后使用内核本身获取WithConstructorArgument绑定中的构造函数参数。之所以这样做,是为了让您可以将自己的IObjectMapper绑定加载到内核中,如果您决定编写自己的自定义映射器。

  • 自行绑定Configuration,然后方法绑定IConfigurationIConfigurationProvider 的原因是,与Windsor不同,Ninject没有提供任何一流的支持来将多个接口绑定到单个目标范围,因此需要这种方式。

就是这些了。编写带有依赖项的容器类,依赖于IConfiguration(如果要创建新的映射)和/或IMappingEngine(用于实际映射),Ninject会毫无问题地注入它们。

如果您想实现超松散的耦合,并且每个映射都定义在自己的类中,那么您可能需要查看Ninject的Convention扩展,它可以进行类似于Windsor的FromAssembly的程序集扫描。这也可以加载您可能在单独的库中定义的任何自定义IObjectMapper类。


1
你是否偶然有一个AutoMapper v2模块,并且/或者一句话解释一下这种策略在v2中是否可行? - Ruben Bartelink
1
@RubenBartelink:你试过将Configuration改为ConfigurationStore吗?我认为这是v2中唯一相关的更改;它实现了与v1中的Configuration相同的IConfiguration接口,并接受与v1中的Configuration相同的构造函数参数。 - Aaronaught
认为Profile也在其中。目前,我有一组通过Ninject.Extensions.Conventions发现的它们,然后将其馈送到Mapper.Initialize()中。可能会重新审视,当我需要注入转换器/格式化程序/任何一个这样的东西时。希望@jbogard能够撰写一篇规范文章和/或更新一两个段落,介绍v2的新抽象如何与DI配合使用,直到那变得关键之前。正在使用反编译器进行分析;需要阅读测试(至少如果想要了解Ninject的最佳方法)。暂时先感谢您的回复和答案。 - Ruben Bartelink
1
@RubenBartelink:我也使用配置文件,但是我没有在这里深入讨论,因为它不是纯的automapper/DI代码。相反,我创建了一个IMapRegistration接口,并且所有实现类都在启动时运行。它们都在构造函数中使用IProfileExpression(仍然是v2 API的一部分),然后我编写了一个名为WithProfile的扩展方法,该方法只是通过使用WithConstructorArgument并在保留上下文的情况下调用IConfiguration get上的CreateProfile方法来创建配置文件。有点啰嗦,但就是这样。 - Aaronaught
听起来很不错(虽然我没有一个中央DLL来放置这样的“IMapRegistration”接口,这就是为什么我选择直接使用它。我想如果你有时间将你的技术整理成一个漂亮的“这就是我如何在AM 2.0中实现它”的答案,那会非常有用:P 在此期间,感谢您分享相关细节。 - Ruben Bartelink

2
public class AutoMapperModule : NinjectModule
{
    public override void Load()
    {
        Bind<IMappingEngine>().ToMethod(ctx => Mapper.Engine);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接