比较映射对象并动态验证映射

时间:2017-07-03 15:05:24

标签: c# .net-core automapper

让我们考虑将匿名类型动态映射到预定义类型:

Mapper.Initialize(cfg => cfg.CreateMissingTypeMaps = true);

var dest = Mapper.Map<Dest>(new {a = 42});

我想确保映射了所有Dest个属性。实际值无关紧要,其他任何值都可以为空。

此检查类似于在每次地图调用之前/之后执行的Mapper.Configuration.AssertConfigurationIsValid()(它不考虑新类型地图)。

简单的属性到属性反射比较不起作用,因为应该考虑Automapper配置(我的意思是所有这些不错的功能,如自动类型转换,展平等)。所以检查应该使用Automapper API ......还是不使用?

P.S。我知道它可以显着降低性能。我们的想法是实现一种代码契约,并仅在开发配置中启用它。有什么建议吗?

2 个答案:

答案 0 :(得分:0)

我认为测试你的映射逻辑的单元测试将完成与你期望的“框架”相同的工作。

只是,而不是直接在代码中使用Automapper,创建包装器,您将在任何需要的位置使用它并将测试

public static class MapperWrapper
{
    public static Dest Map(object source)
    {
        return Mapper.Map<Dest>(source);
    }
}

单元测试将为MapperWrapper.Map方法和Aut​​omapper配置提供“代码合同”。当测试人员使用Automapper配置“玩”时,测试也将对开发人员起到“安全网”的作用。

// In example used
// NUnit as test framework
// FluentAssertions as assertion framework

[TestFixture]
public class MapperWrapperTests
{
    [Test]
    public void Map_ShouldReturnInstanceWithCorrectValueOfAProperty()
    {
        var expectedA = 42;
        var input = new { A = expectedA };

        var actualResult = MapperWrapper.Map(input);

        actualResult.A.Should().Be(expectedA);
    }

    // FluentAssertions framework provide "deep object graph" assertion
    [Test]
    public void Map_ShouldReturnInstanceWithCorrectValues()
    {
        var expectedResult = new Dest
        {
            Id = 42,
            Name = "Forty-Two",
            SomeAnotherType = new AnotherType { IsValid = true }
        };
        var input = new 
        { 
            Id = "42",
            Name = "Forty-Two",
            SomeAnotherType = new { IsValid = true }
        };

        var actualResult = MapperWrapper.Map(input);

        actualResult.ShouldBeEquivalentTo(expectedResult);
    }
}

通过在每个构建上执行这些测试,您将获得有关Automapper配置正确的反馈。

您可以引入抽象(接口或抽象类),而不是使用单例MapperWrapper,使用Automapper方法实现抽象。
通过抽象,您的应用程序将不会严格依赖于Automapper。

答案 1 :(得分:0)

您正在寻找的是AutoMapper配置验证,它会执行您指出的所有验证。但是不要在运行时创建地图,而是先预先创建它们(这样做的好处是不会意外地创建无效/不完整/不可能的地图)。

删除CreateMissingTypeMaps = true部分并创建Profile类型,并对要映射的类型进行明确的CreateMap调用。