使用Ninject注入AutoMapper依赖项

10

我在使用Ninject将AutoMapper注入到ASP.NET MVC 2应用程序中遇到了问题。我使用了Jimmy Bogard在AutoMapper和StructureMap类型配置的帖子作为指南。

public class AutoMapperModule : NinjectModule
{
    public override void Load()
    {
        Bind<ITypeMapFactory>().To<TypeMapFactory>();
        Bind<Configuration>().ToSelf().InSingletonScope().WithConstructorArgument("mapper", MapperRegistry.AllMappers);
        Bind<IConfiguration>().To<Configuration>();
        Bind<IConfigurationProvider>().To<Configuration>();
        Bind<IMappingEngine>().To<MappingEngine>();
    }
}

Ninject在解析Configuration时会抛出异常。

激活IObjectMapper出错 没有可用的匹配绑定,且该类型不能自我绑定。 激活路径:
3) 在类型Configuration的构造函数的mappers参数中注入依赖项IObjectMapper

更新

现在可以使用以下绑定工作:

    Bind<ITypeMapFactory>().To<TypeMapFactory>();
    Bind<Configuration>().ToConstant(new Configuration(Kernel.Get<ITypeMapFactory>(), MapperRegistry.AllMappers())).InSingletonScope();
    Bind<IConfiguration>().ToMethod(c => c.Kernel.Get<Configuration>());
    Bind<IConfigurationProvider>().ToMethod(c => c.Kernel.Get<Configuration>());
    Bind<IMappingEngine>().To<MappingEngine>();

我在GitHub上发布了这个模块。AutoMapper.Ninject。更多信息请参见我的博客:http://binaryspeakeasy.com/2010/09/automapper-ninject/


请参见https://dev59.com/dXI-5IYBdhLWcg3wiY3a#1810728。 - Ruben Bartelink
3个回答

11

你可以使用最新版本(目前为2.2.0)的一行代码来完成这个操作。

kernel.Rebind<IMappingEngine>().ToMethod(context => Mapper.Engine);

另外,我确实同意fodonnel的观点,添加一个门面来隐藏Automapper接口是个好主意,但除非你需要所有这些功能,否则我不会直接从Automapper中获取签名。


2

引入一个映射门面可能也是个不错的主意。不要在代码中传递IMappingEngine,而是创建一个IObjectMapper接口。我使用的接口包含的方法签名直接来自于automapper的代码。

public interface IObjectMapper
{ 
  TDestination Map(TSource source);
  TDestination Map(TSource source, TDestination destination);
  object Map(object source, Type sourceType, Type destinationType);
  object Map(object source, object destination, Type sourceType, Type destinationType);
}

您的配置仍将依赖于Automapper。
我在博客中写了一篇相关文章,链接在这里:http://fodonnel.wordpress.com/2010/09/20/an-object-mapper-facade/

博客链接已失效。 - mlhDev

1

我已经让它工作了,但创建 Configuration 类的实例并不感觉很干净。有什么进一步的建议可以使其更加简洁。

        Bind<ITypeMapFactory>().To<TypeMapFactory>();
        Bind<Configuration>().ToConstant(new Configuration(Kernel.Get<ITypeMapFactory>(), MapperRegistry.AllMappers())).InSingletonScope();
        Bind<IConfiguration>().ToMethod(c => c.Kernel.Get<Configuration>());
        Bind<IConfigurationProvider>().ToMethod(c => c.Kernel.Get<Configuration>());
        Bind<IMappingEngine>().To<MappingEngine>();

1
一般来说,我会说你过度使用了 Bind<IX>().ToMethod(c => c.Kernel.Get<X>()。只需使用 Bind<IX>().To<X>() 即可。 - Ruben Bartelink
1
同样的 Bind<Configuration>().ToConstant(new Configuration(Kernel.Get<ITypeMapFactory>(), MapperRegistry.AllMappers())).InSingletonScope(); 应该映射到 .To<>.WithConstructorArgument.... - Ruben Bartelink

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