让我们考虑将匿名类型动态映射到预定义类型:
Mapper.Initialize(cfg => cfg.CreateMissingTypeMaps = true);
var dest = Mapper.Map<Dest>(new {a = 42});
我想确保映射了所有Dest
个属性。实际值无关紧要,其他任何值都可以为空。
此检查类似于在每次地图调用之前/之后执行的Mapper.Configuration.AssertConfigurationIsValid()
(它不考虑新类型地图)。
简单的属性到属性反射比较不起作用,因为应该考虑Automapper配置(我的意思是所有这些不错的功能,如自动类型转换,展平等)。所以检查应该使用Automapper API ......还是不使用?
P.S。我知道它可以显着降低性能。我们的想法是实现一种代码契约,并仅在开发配置中启用它。有什么建议吗?
答案 0 :(得分:0)
我认为测试你的映射逻辑的单元测试将完成与你期望的“框架”相同的工作。
只是,而不是直接在代码中使用Automapper,创建包装器,您将在任何需要的位置使用它并将测试
public static class MapperWrapper
{
public static Dest Map(object source)
{
return Mapper.Map<Dest>(source);
}
}
单元测试将为MapperWrapper.Map
方法和Automapper配置提供“代码合同”。当测试人员使用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
调用。