AutoMapper 模式是否违反 DDD 原则?
Does AutoMapper pattern violate principle of DDD?
最近在试用Abp框架,很高兴发现它是DDD的一个很好的实现。但是由于它使用 AutoMapper 将 DTO 转换为 Entities/Aggregates,我注意到它能够使我的聚合的私有设置器短路,这显然违反了 DDD 的主要规则。虽然AutoMapper的目标是减少人工操作,但是DDD强调通过私有setter实现不变性
如何才能把这两个看似矛盾的概念弄清楚,并顺利使用这个框架呢?这是否意味着我必须放弃 AutoMapper 以保持 DDD 原则,反之亦然?
我相信 AutoMapper 不是 DDD 的反模式,因为它在社区中非常流行。换句话说,如果 AutoMapper 可以使用反射(据我所知)来设置私有设置器,那么其他任何人都可以。这是否意味着私有 setter 本质上是不安全的?
感谢任何可以帮助我或给我提示的人。
对Abp框架了解不多。私有 setter 只是用于 DDD(封装)的传统 OOP。您应该从聚合中公开 public 方法来改变其状态。 Automapper 可用于您的应用程序层,您可以在其中将 DTO 映射到域构建块(如值对象),并将它们作为参数传递到聚合 public 函数中,这些函数将更改其自身状态并强制执行不变量。话虽如此,并不是每个人都喜欢 Automapper :)
AutoMapper 是:.NET 中基于约定的对象到对象映射器。
AutoMapper本身并没有违背DDD的原则。可能是你如何使用它。
How can I make there two seemingly conflicting concept clear and use this framework smoothly? Does that mean I have to give up AutoMapper to keep DDD principles or vice versa?
不,您不必放弃 AutoMapper。
您可以为每个地图指定 .IgnoreAllPropertiesWithAnInaccessibleSetter
。
相关:How to configure AutoMapper to globally Ignore all Properties With Inaccessible Setter(private or protected)?
In another word, if AutoMapper can use reflection (as I know) to set private setters, anybody else can. Does that means private setters is essentially unsafe?
不是,那说明反射很厉害
How can I make there two seemingly conflicting concept clear and use this framework smoothly?
通过将 AutoMapper 的配置文件配置为使用使用聚合的工厂方法或构造函数的自定义表达式来构造聚合根。这是我的一个项目的示例:
public class BphNomenclatureManagerApplicationAutoMapperProfile : Profile
{
public BphNomenclatureManagerApplicationAutoMapperProfile()
{
CreateMap<BphCompany, BphCompanyDto>(MemberList.Destination);
CreateMap<CreateUpdateBphCompanyDto, BphCompany>(MemberList.Destination)
// invariants preserved by use of AR constructor:
.ConstructUsing(dto => new BphCompany(
dto.Id,
dto.BphId,
dto.Name,
dto.VatIdNumber,
dto.TradeRegisterNumber,
dto.IsProducer
));
}
}
最近在试用Abp框架,很高兴发现它是DDD的一个很好的实现。但是由于它使用 AutoMapper 将 DTO 转换为 Entities/Aggregates,我注意到它能够使我的聚合的私有设置器短路,这显然违反了 DDD 的主要规则。虽然AutoMapper的目标是减少人工操作,但是DDD强调通过私有setter实现不变性
如何才能把这两个看似矛盾的概念弄清楚,并顺利使用这个框架呢?这是否意味着我必须放弃 AutoMapper 以保持 DDD 原则,反之亦然?
我相信 AutoMapper 不是 DDD 的反模式,因为它在社区中非常流行。换句话说,如果 AutoMapper 可以使用反射(据我所知)来设置私有设置器,那么其他任何人都可以。这是否意味着私有 setter 本质上是不安全的?
感谢任何可以帮助我或给我提示的人。
对Abp框架了解不多。私有 setter 只是用于 DDD(封装)的传统 OOP。您应该从聚合中公开 public 方法来改变其状态。 Automapper 可用于您的应用程序层,您可以在其中将 DTO 映射到域构建块(如值对象),并将它们作为参数传递到聚合 public 函数中,这些函数将更改其自身状态并强制执行不变量。话虽如此,并不是每个人都喜欢 Automapper :)
AutoMapper 是:.NET 中基于约定的对象到对象映射器。
AutoMapper本身并没有违背DDD的原则。可能是你如何使用它。
How can I make there two seemingly conflicting concept clear and use this framework smoothly? Does that mean I have to give up AutoMapper to keep DDD principles or vice versa?
不,您不必放弃 AutoMapper。
您可以为每个地图指定 .IgnoreAllPropertiesWithAnInaccessibleSetter
。
相关:How to configure AutoMapper to globally Ignore all Properties With Inaccessible Setter(private or protected)?
In another word, if AutoMapper can use reflection (as I know) to set private setters, anybody else can. Does that means private setters is essentially unsafe?
不是,那说明反射很厉害
How can I make there two seemingly conflicting concept clear and use this framework smoothly?
通过将 AutoMapper 的配置文件配置为使用使用聚合的工厂方法或构造函数的自定义表达式来构造聚合根。这是我的一个项目的示例:
public class BphNomenclatureManagerApplicationAutoMapperProfile : Profile
{
public BphNomenclatureManagerApplicationAutoMapperProfile()
{
CreateMap<BphCompany, BphCompanyDto>(MemberList.Destination);
CreateMap<CreateUpdateBphCompanyDto, BphCompany>(MemberList.Destination)
// invariants preserved by use of AR constructor:
.ConstructUsing(dto => new BphCompany(
dto.Id,
dto.BphId,
dto.Name,
dto.VatIdNumber,
dto.TradeRegisterNumber,
dto.IsProducer
));
}
}