C# DDD-域如何接收客户端数据
我计划重构一个正在维护的遗留.NET项目,主要涉及4个项目:C# DDD-域如何接收客户端数据,c#,design-patterns,domain-driven-design,C#,Design Patterns,Domain Driven Design,我计划重构一个正在维护的遗留.NET项目,主要涉及4个项目: My.Company.Web-表示层。NETMVC My.Company.Service-服务层,定义服务接口并包含命令处理程序。由web层调用 My.Company.DTO-包含用于域和web层之间数据传输的DTO类的程序集 My.Company.Domain-域层 My.Company.Data-持久层 当用户提交表单以更新某人的详细信息时,该过程看起来有点像: 控制器使用提交的数据构造一个PersondetailsTo,该对
-表示层。NETMVCMy.Company.Web
-服务层,定义服务接口并包含命令处理程序。由web层调用My.Company.Service
-包含用于域和web层之间数据传输的DTO类的程序集My.Company.DTO
-域层My.Company.Domain
-持久层My.Company.Data
PersondetailsTo
,该对象由多个简单字段组成,用于保存FirstName
、LastName
、Age
等,以及一个名为addressedTo
的复杂类型对象,该对象保存地址详细信息:var dto=new PersonDetails(…)代码>
_personService.UpdateDetails(dto);
public void UpdatePerson(PersonDetailsDTO dto)
{
var person = _personRepository.GetById(dto.PersonId);
person.Update(dto);
_personRepository.Update(person);
}
public class Person : AggregateRoot
{
private string FirstName;
.... // other fields
private Address Address;
public void Update(PersonDetailsDTO dto)
{
FirstName = dto.FirstName;
.... // other fields
Address.Update(dto.AddressDTO); // update the value object - address
}
}
Person
域引用了PersonDetailsDTO
。我觉得这是不对的,因为DTO是将域中的数据呈现给其客户机的手段,而不公开域本身。域应该而不是关注它如何呈现给客户
此外,在我看来,DTO应该存在于My.Company.Service
项目中,因为它是定义操作/数据传输合同的服务
但是,服务如何将详细信息传递给域呢?它必须是一个冗长的参数列表:person.Update(名字、姓氏、年龄、性别、街道1、街道2、州、邮政编码……
)。这在我看来肯定是错的
或者域必须定义另一组自己的“DTO”来接收客户端数据吗
我已经阅读了很多教程和帖子,似乎没有人分享我的担忧,所以我开始觉得我在这里遗漏了一些东西,有人能给我指出正确的方向吗?你可以这样做。
您已经有一个名为Address
的值对象,类似地,您可以有另一个名为PersonalDetails
的值对象,该值对象将包含名字、姓氏、年龄、性别等。Person
实体将有两种行为,如updatePersonalDetails()
和updateAddress()
。您的应用程序服务如下所示
public void UpdatePerson(PersonDetailsDTO dto)
{
var person = _personRepository.GetById(dto.PersonId);
Address address = new Address(dto.getStreet1, dto.getStreet2,...);
PersonalDetails details = new PersonalDetails(dto.getFirstName,dto.getLastName(),...);
person.updatePersonalDetails(details);
person.updateAddress(address);
_personRepository.save(person);
}
你可以这样做。
您已经有一个名为Address
的值对象,类似地,您可以有另一个名为PersonalDetails
的值对象,该值对象将包含名字、姓氏、年龄、性别等。Person
实体将有两种行为,如updatePersonalDetails()
和updateAddress()
。您的应用程序服务如下所示
public void UpdatePerson(PersonDetailsDTO dto)
{
var person = _personRepository.GetById(dto.PersonId);
Address address = new Address(dto.getStreet1, dto.getStreet2,...);
PersonalDetails details = new PersonalDetails(dto.getFirstName,dto.getLastName(),...);
person.updatePersonalDetails(details);
person.updateAddress(address);
_personRepository.save(person);
}
根据和DDD,值对象
(您所称的dto
:PersonDetailsDTO
和地址
)应由域指定。这意味着它们应该位于域名称空间/包/项目中。顺便说一句,那些值对象
可以一直使用到表示层,然后再使用
其次,它们不是dto
(数据传输对象),因为不涉及昂贵的远程调用,而是值对象(内聚数据和可能的行为);了解更多如何不将其用作反模式
最后但并非最不重要的一点是,您应该使用通用语言中的术语命名方法(person.Update
似乎不是来自UL)。我不是说100%是你的情况,因为我不知道你的领域,我只是说你应该注意这些重要的细节(命名事物)。根据和DDD,值对象
(你称之为dto
:persondeailsdo
和地址
)域应。这意味着它们应该位于域名称空间/包/项目中。顺便说一句,那些值对象
可以一直使用到表示层,然后再使用
其次,它们不是dto
(数据传输对象),因为不涉及昂贵的远程调用,而是值对象(内聚数据和可能的行为);了解更多如何不将其用作反模式
最后但并非最不重要的一点是,您应该使用通用语言中的术语命名方法(person.Update
似乎不是来自UL)。我不是说100%是你的情况,因为我不知道你的领域,我只是说你应该注意这些重要的细节(命名事物)。你需要实现对象到对象的映射。这意味着服务层负责通过映射从客户机接收的DTO实例的值来创建和填充基于DTO的域对象
您可以利用库简化对象到对象的映射。
当然,如果需要,可以为域到DTO提供服务。您需要实现对象到对象的映射。这意味着服务层负责通过映射从客户机接收的DTO实例的值来创建和填充基于DTO的域对象
您可以利用库简化对象到对象的映射。
当然,如果需要,可以为域到DTO提供服务。我很确定您不想更新一个人(规则可能有例外,但通常这听起来像CRUD术语,您希望在DDD中避免)。也许是你感兴趣的。是的,这是一个很好的观点,谢谢。我会看一看:)我很确定你不想更新per