【问题标题】:Auto mapper - how can I automatically create maps and avoid explicit map creation? (10.0+)Automapper - 如何自动创建地图并避免显式创建地图? (10.0+)
【发布时间】:2021-06-15 15:05:27
【问题描述】:

我正在寻找一些实用程序,使用它可以避免编写额外的代码行。

举例

config.CreateMap<ModelClass, DTOClass>();

虽然我没有ModelClass和DTOClass之间的任何区别,但我仍然需要创建地图或automapper可以自己做吗?

【问题讨论】:

  • 你应该在 appDomain 中调用一次映射器配置
  • @BijuKalanjoor 你能解释一下吗?
  • @StuartLC 是否也适用于自动映射器版本 10.1.1.0 ?
  • No,但是如果对象看起来完全一样,为什么还要费心两个对象呢?
  • @StuartLC 据我了解,CreateMissingTypeMaps 已从 9.0 及更高版本中删除

标签: c# automapper


【解决方案1】:

根据 cmets,Automapper 团队似乎选择删除 9.0 upgrade 中的 CreateMissingTypeMaps 选项。推测,这是因为自动地图创建可能会导致意外的映射和尴尬的运行时错误,而且,最好在引导时定义所有地图并编译它们,而不是在第一次映射时懒惰地编译它们。

但是,如果您在 Poco 类层之间使用一致的命名方案,则可以很容易地在引导时为两个 poco 层中具有相同名称的所有类复制自动映射功能。例如,如果您的约定是:

namespace Models
{
    public class MyModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Amount { get; set; }
        public DateTime Date { get; set; }
    }
}

namespace Dtos
{
    public class MyDto
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Amount { get; set; }
        public DateTime Date { get; set; }
    }
}

然后,您可以在每一层中反映所有符合您命名约定的类,并在匹配的类之间显式创建映射:

const string modelSuffix = "Model";
const string dtoSuffix = "Dto";
var mapperConfiguration = new MapperConfiguration(cfg =>
{
    // You may need to repeat this if you have Pocos spread across multiple assemblies
    var modelTypes = typeof(MyModel).Assembly
        .GetTypes()
        .Where(type => type.Namespace == "Models" && type.Name.EndsWith(modelSuffix))
        .ToDictionary(t => StripSuffix(t.Name, modelSuffix));

    var dtoTypes = typeof(MyDto).Assembly
        .GetTypes()
        .Where(type => type.Namespace == "Dtos"
                       && type.Name.EndsWith(dtoSuffix));

    foreach (var dtoType in dtoTypes)
    {
        if (modelTypes.TryGetValue(StripSuffix(dtoType.Name, dtoSuffix), out var modelType))
        {
            // I've created forward and reverse mappings ... remove as necessary
            cfg.CreateMap(dtoType, modelType);
            cfg.CreateMap(modelType, dtoType);
        }
    }
});
var mapper = mapperConfiguration.CreateMapper();

StripSuffixis simply:

public static string StripSuffix(string someString, string someSuffix)
{
    if (someString.EndsWith(someSuffix))
        return someString.Substring(0, someString.Length - someSuffix.Length);
    else
        return someString;
}

您现在可以根据需要进行测试:

var model = new MyModel
{
    Id = 1,
    Name = "Foo",
    Amount = 1.23m,
    Date = DateTime.UtcNow
};

var dto = mapper.Map<MyDto>(model);
var backTomodel = mapper.Map<MyModel>(dto);

【讨论】:

  • 可以,或者干脆使用属性映射。自动地图在非常简单的情况下工作。然后事情不再那么简单了:) 没有简单的方法可以将它们隔离到简单的情况下。您可以使用多个 MappingConfigurations 来做到这一点,但没有人这样做。
  • 是的,好点。老实说,我很久以前就停止使用CreateMissingTypeMaps,并且没有意识到它已经完全被放弃了——正如你所说,最好让事情变得明确并更好地控制映射的发生方式。像许多人一样,我非常反对使用映射或 IoC 关注点等属性污染多层类,因为这会在这些程序集中产生额外的耦合。
猜你喜欢
  • 1970-01-01
  • 2018-02-04
  • 1970-01-01
  • 1970-01-01
  • 2015-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多