【问题标题】:Using Profiles in Automapper to map the same types with different logic在 Automapper 中使用 Profiles 来映射具有不同逻辑的相同类型
【发布时间】:2011-01-12 02:35:53
【问题描述】:

我在我的 ASP.NET MVC 网站中使用 AutoMapper 将我的数据库对象映射到 ViewModel 对象,并且我正在尝试使用多个配置文件来映射相同的类型,但使用了另一种逻辑。通过阅读Matt's blog post 他说:

真正关键的部分是 AutoMapper 配置文件。您可以使用配置文件对配置进行分组。也许在一个配置文件中您以一种方式格式化日期,在另一个配置文件中您以另一种方式格式化日期。我在这里只使用一个配置文件。

所以我为一个案例创建了一个配置文件:

public class MyProfile : Profile
{
    protected override string ProfileName
    {
        get
        {
            return "MyProfile";
        }
    }

    protected override void Configure()
    {
        CreateMap<DateTime, String>().ConvertUsing<StringFromDateTimeTypeConverter>();
    }
}

public class StringFromDateTimeTypeConverter : ITypeConverter<DateTime, String>
{
    public string Convert(DateTime source)
    {
        return source.ToString("dd/mm/yyyy", CultureInfo.InvariantCulture);
    }
}

另外一个案例:

public class MyProfile2 : Profile
{
    protected override string ProfileName
    {
        get
        {
            return "MyProfile2";
        }
    }

    protected override void Configure()
    {
        CreateMap<DateTime, String>().ConvertUsing<AnotherStringFromDateTimeTypeConverter>();
    }
}

public class AnotherStringFromDateTimeTypeConverter : ITypeConverter<DateTime, String>
{
    public string Convert(DateTime source)
    {
        return source.ToString("mm - yyyy", CultureInfo.InvariantCulture);
    }
}

但是,我找不到用于指定配置文件的 Mapper.Map&lt;&gt;() 方法的任何重载。我还查看了 Configuration 对象,但没有运气。
最后注册的配置文件始终优先。

有没有办法为此目的使用配置文件?

【问题讨论】:

    标签: c# automapper


    【解决方案1】:

    从 AutoMapper v10 开始。您需要实例化一个IMapper,它使用您想要的特定Profile。像这样的:

    MapperConfiguration config = new MapperConfiguration(cfg => {
        cfg.AddProfile(new MyProfile());
    });
    IMapper mapper = new Mapper(config);
    var myHuman = mapper.map<Human>(myPerson);
    

    可以使用小写或大写的NamePerson 映射到Human 的示例。

    class Program
    {
        static void Main(string[] args)
        {
            Person myPerson = new Person
            {
                Name = "HAzEL NUtt"
            };
            Console.WriteLine(myPerson.Name);
    
            MapperConfiguration configUpper = new MapperConfiguration(cfg => {
                cfg.AddProfile(new UpperCaseProfile());
            });
            IMapper mapperUpper = new Mapper(configUpper);
            Console.WriteLine(mapperUpper.Map<Human>(myPerson).Name);
    
            MapperConfiguration configLower = new MapperConfiguration(cfg => {
                cfg.AddProfile(new LowerCaseProfile());
            });
            IMapper mapperLower = new Mapper(configLower);
            Console.WriteLine(mapperLower.Map<Human>(myPerson).Name);
        }
    }
    
    public class LowerCaseProfile : Profile
    {
        public LowerCaseProfile()
        {
            CreateMap<Person, Human>()
                    .ForMember(d => d.Name, opt => opt.MapFrom(src => src.Name.ToLower()));
        }
    }
    
    public class UpperCaseProfile : Profile
    {
        public UpperCaseProfile()
        {
            CreateMap<Person, Human>()
                .ForMember(d => d.Name, opt => opt.MapFrom(src => src.Name.ToUpper()));
        }
    }
    

    这是输出:

    HAzEL NUtt
    HAZEL NUTT
    hazel nutt
    

    【讨论】:

      【解决方案2】:

      配置文件用于分离跨多个类型映射应用的通用配置,例如格式化。但是,类型映射仍然是全局的。您最好创建单独的配置对象,并为每个对象创建一个单独的 MappingEngine。 Mapper 类只是其中每一个的静态外观,具有一些生命周期管理。

      【讨论】:

      • 如果没有锁定,那会是线程安全的吗?例如,'MapperRegistry.AllMappers()' 是静态的,而 'TypeMapFactory' 有一个静态字典。
      • 通常每个 AppDomain 在启动时只调用一次配置。您只需要在您拥有的任何托管模型中找到合适的接缝(WCF、ASP.NET、WinForms 等不同)
      • @sebd:你有没有想过,我们如何为同一类型保留多个映射?这会很有帮助,例如在与 Ignore 配置结合使用的情况下。
      • 如何实现 IConfigurationProvider 的示例或使用提供配置的新 MappingEngine 的示例会很棒。 AutoMapper 的稀疏文档使得这些更复杂的场景有点棘手。有人可以用一点代码改进这个答案吗?
      • 我花了 20 分钟才找到问题的答案。答案就在您的句子中:“Profiles are for segregating common configuration”。谢谢。
      猜你喜欢
      • 2016-10-13
      • 1970-01-01
      • 2018-08-17
      • 2017-07-08
      • 2014-09-23
      • 1970-01-01
      • 2012-02-10
      • 1970-01-01
      • 2021-07-22
      相关资源
      最近更新 更多