代码之家  ›  专栏  ›  技术社区  ›  Femaref

automapper和依赖注入

  •  20
  • Femaref  · 技术社区  · 15 年前

    我目前有以下映射:

    Mapper.CreateMap<Journal, JournalDto>();
    

    现在, Journal 包含名为的成员 RefTypeID ,数据库中的另一个表中存在对应的值;要查找该值,我有一个服务可以处理一个简单的 int -> string 请求。automapper配置当前发生在程序开始时的静态类中。是否可以将映射代码移动到一个注入到DI容器的类中,或者有更好的方法?

    4 回复  |  直到 15 年前
        1
  •  15
  •   Michał Powaga Mohamed Aslam    12 年前

    更好的方法是使用客户分解器。映射配置是静态的,因此自定义冲突解决程序旨在为单个成员提供映射:

    Mapper.Initialize(cfg => {
        cfg.ConstructServicesUsing(type => WhateverMefUsesToGetInstances.GetInstance(type));
    
        cfg.CreateMap<Journal, DisplayJournal>()
            .ForMember(dest => dest.RefTypeName, 
                opt => opt.ResolveUsing<RefTypeNameResolver>());
    });
    

    然后你的解析器变成:

    [Export(typeof(IRefTypeNameResolver))]
    public class RefTypeNameResolver : ValueResolver<Journal, string>, IRefTypeNameResolver
    {
        private readonly IRefTypesLookup iRefTypesLookup;
    
        [ImportingConstructor]
        public RefTypeNameResolver (IRefTypesLookup rtl)
        {
            iRefTypesLookup = rtl;
        }
    
        protected override string ResolveCore(Journal source)
        {
            return iRefTypesLookup.Lookup(source.RefTypeID);
        }
    }
    

    配置需要执行一次,这就是配置API向执行API(类型转换器、值解析器等)提供挂钩的原因。

        2
  •  14
  •   Martin R-L    14 年前

    你可以依赖 IMappingEngine 而不是使用静态类 Mapper .

    这里有一篇很好的博客: Mocking out AutoMapper with Dependency Injection

        3
  •  9
  •   Femaref    15 年前

    我是这样解决的:

    我定义了一个 IMappingCreator 接口:

    public interface IMappingCreator
    {
      void CreateMappings();
    }
    

    我接着用这个接口实现了一个类(我使用mef作为DI容器,这是属性的混合来源),它作为 想象创建者 :

    [Export(typeof(IMappingCreator))]
        public class Mapping : IMappingCreator
        {
            private readonly IRefTypesLookup iRefTypesLookup;
    
    
            [ImportingConstructor]
            public Mapping(IRefTypesLookup rtl)
            {
                iRefTypesLookup = rtl;
            }
    
            public void CreateMappings()
            {
                Mapper.CreateMap<Journal, DisplayJournal>().AfterMap((j, dj) => dj.RefTypeName = iRefTypesLookup.Lookup(j.RefTypeID));
            }
        }
    

    最后,在应用程序启动时,我在容器中获取该接口的所有实例并调用 CreateMappings 方法:

        var mappings = container.GetExportedValues<IMappingCreator>();
    
        foreach (IMappingCreator mc in mappings)
        {
            mc.CreateMappings();
        }
    

    这使得初始设置非常容易,因为所有的创建都发生在一个地方,并且您可以有任意多的映射创建者(但是,您应该将这些保持在最低限度,可能每个项目一次左右,获取映射该项目中特定类型所需的所有服务)。

        4
  •  2
  •   Gene S    9 年前

    这是最新的方法……

    https://pintoservice.wordpress.com/2016/01/31/dependency-injection-for-automapper-4-2-in-asp-net-vnext-mvc-project/

    尽管我个人将自动映射添加到控制器中,而不是存储库中。这样,您就可以为不同的控制器使用相同的存储库,并具有不同的映射。同样的概念,只需注入 IMapper 在控制器而不是存储库中。

    推荐文章