![](/img/trans.png)
[英]Automapper -AutoMapper.AutoMapperMappingException
[英]Automapper and immutability
是否可以将 AutoMapper 与不可变类型一起使用?
例如我的域类型是不可变的,我想将我的视图类型映射到这个。
我相信它不是,但只是想确认这一点。
此外,由于域类型不可变是最佳实践,因此将视图类型映射到域类型时的最佳实践是什么?
我通常手动进行从视图类型到域类型的映射,因为我通常会通过更复杂的接口、使用方法等进行工作。 如果您使用 AutoMapper 从视图到域,您现在被锁定在一个贫血的域模型中,无论您是否有意决定。
假设您确实想要域类型的不可变属性,例如Id
。 您的域类型可能如下所示:
public class DomainType
{
public DomainType(int id)
{
Id = id;
}
public int Id { get; }
// other mutable properties
// ...
}
然后,您可以使用您选择的公共构造函数来使用ConstructUsing
,例如:
CreateMap<ViewType, DomainType>()
.ConstructUsing(vt => new DomainType(vt.Id));
然后以正常方式映射所有可变属性
AutoMapper 依赖属性设置器来完成它的工作,所以如果你有只读属性,AutoMapper 将没有多大用处。
您可以覆盖映射行为,例如,将其配置为调用特定的构造函数,但这基本上违背了 AutoMapper 的目的,因为那时您正在手动进行映射,并且您只能成功地在过程。
你的域模型是不可变的,这对我来说没有多大意义。 你如何更新它? 整个应用程序是只读的吗? 如果是这样,为什么您需要映射到域模型而不是from ? 一个不可变的域模型听起来……很没用。
PS 我假设你的意思是这个 AutoMapper而不是Fluent NHibernate 中的自动映射功能,甚至是其他一些完全不同的东西。 如果那是错误的,那么您应该更具体并为您的平台/语言添加标签。
我们有使用构建器模式的不可变对象。 映射它们需要更多的样板代码,但这是可能的
// ViewModel
public class CarModel : IVehicleModel
{
private CarModel (Builder builder)
{
LicensePlate = builder.LicensePlate;
}
public string LicensePlate { get; }
//
public Builder
{
public string LicensePlate { get; set; }
}
}
// Model
public class CarViewModel : IVehicleViewModel
{
private CarViewModel (Builder builder)
{
LicensePlate = builder.LicensePlate ;
}
public ILicensePlate LicensePlate { get; }
//
public Builder
{
public ILicensePlate LicensePlate { get; set; }
}
}
我们的AutoMapper Profiles
注册了三个映射:
CreateMap<IVehicleModel, CarViewModel.Builder>();
CreateMap<CarViewModel.Builder, IVehicleViewModel>().ConvertUsing(x => x.Build());
CreateMap<IVehicleModel, IVehicleViewModel>().ConvertUsing<VehicleModelTypeConverter>();
VehicleModelTypeConverter
然后定义了一个两阶段的转换:
public IVehicleViewModel Convert(IVehicleModel source, IVehicleViewModel destination,
ResolutionContext context)
{
var builder = context.Mapper.Map<CarViewModel.Builder>(source);
var model = context.Mapper.Map<IVehicleViewModel>(builder);
return model;
}
( ITypeListConverter<string, ILicensePlate>
执行该映射)。
在我们的系统中使用是正常的:
var result = _mapper<IVehicleViewModel>(_carModel);
这是使用 AutoMapper v7.0.1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.