我们有一个旧的(手摇式)系统,它使用反射将一个模型映射到另一个模型。这使用模型上的属性来确定需要传输的内容。此转换在运行时在共享项目的基类内处理。
我正在考虑用 Automapper 的实现在较低级别替换它 - 在测试期间,这似乎在大容量下明显更快。
我想做的是继续使用遗留机制来生成地图以保持一致性。我可以使用下面的代码成功地做到这一点:
public static IMapper CreateMap()
{
var configuration = new MapperConfiguration(
BuildMapForModel<ModelA, ModelB>);
var map = configuration.CreateMapper();
return map;
}
public static void BuildMapForModel<TIn, TOut>(IMapperConfigurationExpression config)
{
var expression = config.CreateMap<TIn, TOut>();
//Build the mapping with reflection.
foreach (var propertyInfo in typeof(TOut).GetProperties())
{
var attribute = propertyInfo.GetCustomAttribute(typeof(CustomMappingAttribute)) as CustomMappingAttribute;
if (attribute == null)
{
expression.ForMember(propertyInfo.Name, opt => opt.Ignore());
}
else
{
var sourceproperty = attribute.SourcePropertyName;
expression.ForMember(propertyInfo.Name, map => map.MapFrom(sourceproperty));
}
}
expression.ReverseMap();
}
这工作正常。然而,它依赖于每次为每个类构建映射。相反,我想让MapperConfiguration
对象静态化,以便它可以重复使用。此外,我希望能够根据需要添加到映射列表中。
即,当我的代码请求ModelA 和ModelB 之间的映射时,我想确定我是否已经有一个映射,如果没有,运行代码来映射它。
private static MapperConfiguration Configuration { get; set; }
public static TOut Convert<TIn, TOut>(TIn item)
{
if (Configuration == null)
{
//Create a new configuration object.
}
if (Configuration.FindTypeMapFor<TIn, TOut>() == null)
{
//Add a mapping to the configuration - via BuildMapForModel.
}
var map = Configuration.CreateMapper();
return map.Map<TIn, TOut>(item);
}
但是,MapperConfiguration
似乎不允许在创建后添加映射,也似乎不允许无参数构造函数。
如何设置它以便仅在必要时运行映射代码,但避免每次都运行它?