将域实体作为paremeter发送或将实体id作为参数发送到应用服务中

ryu*_*ice 8 c# architecture domain-driven-design

在使用域驱动设计时,您的服务方法是否更好地将实体作为参数或实体的id作为参数接收,以便您可以使用存储库检索方法内的实体?

例如:

public void Apply(Job job, User user)
Run Code Online (Sandbox Code Playgroud)

public void Apply(int jobId, int userId)
Run Code Online (Sandbox Code Playgroud)

Nie*_*est 8

DDD是将客户的词汇量映射到您的设计.您的客户(希望)谈论申请工作的用户,而不是某个整数ID链接到另一个整数ID.尝试尽可能地贴近现实世界,除非它成为负担.

通过传入整个实体,您可以立即从实体的行为中受益,而无需首先构建它.

所以坚持使用实体,除非您经常只有一个ID可以使用.当您处理外部系统(例如Web服务)时,通常会发生这种情况.在这种情况下,您可以创建一个接受ID的方法重载.此重载应验证ID,构造实体并调用接受实体的重载.

public void Apply(int jobId, int userId)
{
    // Validate the IDs.

    // Construct the entities.
    var job = ...;
    var user = ...;

    // Call the 'proper' overload.
    Apply(job, user);
}

public void Apply(Job job, User user)
{
    // Actual business logic belongs here.
}
Run Code Online (Sandbox Code Playgroud)

再次:尝试尽可能避免这种重载,除非您正在处理仅返回ID的外部系统.

从编码的角度来看,实体也比整数更好.整数可以是任何整数值,因此您必须在使用它的任何地方对其进行验证.您的工厂负责构建有效实体,您的(域)逻辑应使您的实体保持有效状态.因此,使用该实体是完全安全的,不需要太多验证.


Vij*_*tel 5

这取决于在那里你的应用服务所在:

如果您的服务在同一AppDomain中执行(即,您从同一可执行文件调用它),则传递对象是理想的。服务可以轻松访问对象图中的其他对象。

如果您的服务在其他AppDomain中执行(例如,在WebService或其他远程位置之后),则应使用ID。然后,服务将在使用之前从持久性存储中加载适当的对象。

如果尝试通过电线发送对象,则可能会遇到此处描述问题

希望能有所帮助。


M.S*_*eer 1

如果发送对象,则会在服务和实体之间创建依赖关系。使用服务的优点之一是充当外观,以减少类之间的依赖关系图并降低设计的复杂性。最好在服务契约中使用原始类型、结构体、枚举,但在处理大量方法参数时,您可以将它们封装在一个对象中,但在这种情况下,它将是 DTO 而不是实体。