Для такой проблемы я бы рекомендовал использовать метод GetUnmappedPropertyNames
IMapper
. Код и тест должен объяснить идею ниже:
Условие (z.PropertyType.IsValueType || z.PropertyType.IsArray || z.PropertyType == TypeOf (строка))
обнаружит неотображённые свойства от Типы значений, такие как int, enum, Guid, DateTime, все типы Nullable value bool ?, Decimal ?, Guid ?, и string.
И такой фильтр пусть ваш тест игнорировать отображение для Entity Навигация свойств вида:
public virtual Class NavigationProperty {get;set}
public virtual IList<Class> CollectionNavigationProperty { get; set; }
код и тест:
[Test]
public void Mapping_Profile_Must_Not_Have_Unmapped_Properties()
{
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<TestProfile>();
});
var mapper = config.CreateMapper();
var unmappedProperties = GetUnmappedSimpleProperties(mapper);
Assert.AreEqual(unmappedProperties.Count, 0);
}
private List<UnmappedProperty> GetUnmappedSimpleProperties(IMapper mapper)
{
return mapper.ConfigurationProvider.GetAllTypeMaps()
.SelectMany(m => m.GetUnmappedPropertyNames()
.Where(x =>
{
var z = m.DestinationType.GetProperty(x);
return z != null && (z.PropertyType.IsValueType || z.PropertyType.IsArray || z.PropertyType == typeof(string));
})
.Select(n => new UnmappedProperty
{
DestinationTypeName = m.DestinationType.Name,
PropertyName = n,
SourceTypeName = m.SourceType.Name
})).ToList();
}
internal class UnmappedProperty
{
public string PropertyName { get; set; }
public string DestinationTypeName { get; set; }
public string SourceTypeName { get; set; }
public override string ToString()
{
return $"{this.PropertyName}: {this.SourceTypeName}->{this.DestinationTypeName}";
}
}
Proving тест к вашим услугам:
[Test]
public void Test_Mapping_Profile_Must_Detect_Unmapped_Properties()
{
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<TestMappingProfile>();
});
ar mapper = config.CreateMapper();
var unmappedProperties = GetUnmappedSimpleProperties();
Assert.AreEqual(unmappedProperties.Count, 12);
}
public class TestMappingProfile : Profile
{
public TestMappingProfile()
{
CreateMap<Source, DestinationValid>();
CreateMap<Source, DestinationInvalid>();
}
}
internal class Source
{
public string Test1 { get; set; }
public int Test2 { get; set; }
public int? Test3 { get; set; }
public decimal Test4 { get; set; }
public string[] Test5 { get; set; }
public Guid Test6 { get; set; }
public Guid? Test7 { get; set; }
public TransactionRealm Test8 { get; set; }
public bool? Test9 { get; set; }
public bool Test10 { get; set; }
public DateTime Test11 { get; set; }
public DateTime? Test12 { get; set; }
}
internal class DestinationValid
{
public string Test1 { get; set; }
public int Test2 { get; set; }
public int? Test3 { get; set; }
public decimal Test4 { get; set; }
public string[] Test5 { get; set; }
public Guid Test6 { get; set; }
public Guid? Test7 { get; set; }
public TransactionRealm Test8 { get; set; }
public bool? Test9 { get; set; }
public bool Test10 { get; set; }
public DateTime Test11 { get; set; }
public DateTime? Test12 { get; set; }
}
internal class DestinationInvalid
{
public string Test1X { get; set; }
public int Test2X { get; set; }
public int? Test3X { get; set; }
public decimal Test4X { get; set; }
public string[] Test5X { get; set; }
public Guid Test6X { get; set; }
public Guid? Test7X { get; set; }
public TransactionRealm Test8X { get; set; }
public bool? Test9X { get; set; }
public bool Test10X { get; set; }
public DateTime Test11X { get; set; }
public DateTime? Test12X { get; set; }
}
где TransactionRealm является примером перечисления:
public enum TransactionRealm
{
Undefined = 0,
Transaction = 1,
Fee = 2,
}
когда вы надеетесь, что это автоматическое обнаружение произойдет? С помощью инструмента, вызывающего? –
Мы планировали написать модульные тесты, а также сделать это для каждой пары не представляется возможным. –