首页 文章

如何使用StructureMap注入AutoMapper IMappingEngine

提问于
浏览
14

我为Automapper找到的大多数示例都使用静态Mapper对象来管理类型映射 . 对于我的项目,我需要使用StructureMap注入IMapperEngine作为对象构造的一部分,以便我们可以在单元测试中模拟映射器,因此我们不能使用静态映射器 . 我还需要支持配置AutoMapper配置文件 .

我的问题是如何配置StructureMap注册表,以便在构造MyService实例时它可以提供IMappingEngine的实例 .

这是Service构造函数签名:

public MyService(IMappingEngine mapper, IMyRepository myRepository, ILogger logger)

这是StructureMap注册表

public class MyRegistry : StructureMap.Configuration.DSL.Registry
{
    public MyRegistry()
    {
        For<IMyRepository>().Use<MyRepository>();
        For<ILogger>().Use<Logger>();
        //what to do for IMappingEngine?
    }
}

我要加载的配置文件

public class MyAutoMapperProfile : AutoMapper.Profile
{
    protected override void Configure()
    {
        this.CreateMap<MyModel, MyDTO>();
    }
}

4 回答

  • 1

    Mapper 类具有静态属性 Mapper.Engine . 使用此命令向容器注册引擎:

    For<IMappingEngine>().Use(() => Mapper.Engine);
    

    如果您需要在注入引擎之前加载配置文件,我会在上面的代码段旁边插入配置代码 .


    Update

    您的自定义注册表将如下所示

    class MyRegistry : Registry
    {
      public MyRegistry()
      {
        For<IMyRepository>().Use<MyRepository>();
        For<ILogger>().Use<Logger>();
    
        Mapper.AddProfile(new AutoMapperProfile());
        For<IMappingEngine>().Use(() => Mapper.Engine);
      }
    }
    

    此代码在您的引导程序中运行一次,之后所有类型为 IMappingEngine 的依赖项将使用您使用自定义 AutoMapperProfile 配置的静态属性 Mapper.Engine 的值提供 .

  • 7

    将在5.0版中删除静态API . 使用MapperConfiguration实例并根据需要静态存储 . 使用CreateMapper创建映射器实例 .

    在新版本(4.2.0> =)中,我们应该通过DI保持并传递 IMapper .

    一个简单的配置服务应该是这样的(ASP.NET核心)

    services.AddSingleton<IMapper>(_ => new MapperConfiguration(cfg =>
                {
                    cfg.CreateMap<Foo,Bar>();
                })
                .CreateMapper());
    

    和我们的服务层(在构造函数注入的帮助下):

    public class CrudService<TDocument> : ICrudService<TDocument>
        {
            private readonly IMapper _internalMapper;
            private readonly IRepository<TDocument> _repository;
    
            public CrudService(IRepository<TDocument> repository, IMapper mapper)                
            {
                _internalMapper = mapper;
                _repository = repository;
            }
    
            public virtual ServiceResult<string> Create<TModel>(TModel foo)
            {
                var bar = _internalMapper.Map<TDocument>(foo);
    
                try
                {
                    _repository.Create(bar);
                }
                catch (Exception ex)
                {
                    return ServiceResult<string>.Exception(ex);
                }
    
                return ServiceResult<string>.Okay(entity.Id);
            }
    }
    

    consider TDocument as Bar, and TModel as Foo


    更新:
    AutoMapper 4.2.1 released – Static is back

    经过一些反馈和灵魂搜索,并且老老实实地厌倦了处理问题,本版本中还恢复了一些静态API . 您现在(以及将来)可以使用Mapper.Initialize和Mapper.Map

  • 1

    我写了一篇博文,其中显示了我的AutoMapper和StructureMap设置 . 我已经为AutoMapper 3.1.0(也适用于3.1.1)和3.0.0和2.2.1创建了特定的注册表 .

    http://www.martijnburgers.net/post/2013/12/20/My-AutoMapper-setup-for-StructureMap.aspx

  • 14

    这是我最终得到的结果,因为我无法弄清楚如何在Mapper.Engine上设置配置并将其传递给For() . 使用 .

    public MyRegistry()
    {
        For<IMyRepository>().Use<MyRepository>();
        For<ILogger>().Use<Logger>();
    
        //type mapping
        For<ConfigurationStore>()
            .Singleton()
            .Use(ctx =>
            {
                ITypeMapFactory factory = ctx.GetInstance<ITypeMapFactory>();
                ConfigurationStore store 
                    = new ConfigurationStore(factory, MapperRegistry.AllMappers());
                IConfiguration cfg = store;
                cfg.AddProfile<MyAutoMapperProfile>();
                store.AssertConfigurationIsValid();
                return store;
            });
        For<IConfigurationProvider>().Use(ctx => ctx.GetInstance<ConfigurationStore>());
        For<IConfiguration>().Use(ctx => ctx.GetInstance<ConfigurationStore>());
        For<IMappingEngine>().Singleton().Use<MappingEngine>();
        For<ITypeMapFactory>().Use<TypeMapFactory>();
    }
    

相关问题