且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

再次将服务注入域对象

更新时间:2023-12-03 14:41:52

处理领域对象需要与服务协作的情况的一种常用方法是在方法级别注入这些服务并应用ISP原理以确保依赖性不会超出所需范围。

A common way of handling cases where domain objects needs to collaborate with services is to inject these services at the method level and apply the ISP principle to ensure the dependencies are not wider than needed.

例如 addPoint(point:Point,geoService:GeoService)

处理该问题的另一种常用方法是解决依赖于应用程序服务的依赖关系,并将结果传递给聚合方法,但是当该方法在应用程序层内部泄漏太多逻辑时,您可能应该在方法级别使用服务注入。

Another common way of dealing with the problem is to resolve the dependency from the application service and pass the result into the aggregate method, but when that approach is leaking too much logic inside the application layer you should probably use service injection at the method level instead.


但是您能详细说明一下后一种解决方案吗?

but could you elaborate a little more about the latter solution

好吧,假设项目聚合必须以最终一致的方式根据其链接的任务聚合来调整其完成状态和百分比。为此,项目必须找出到目前为止已完成的任务。

Well imagine that a Project aggregate must adjust it's completion status and percentage based on it's linked Tasks aggregates in an eventually consistent manner. To do so the Project must find out how many tasks are completed so far.

而不是传递 TaskRepository / TaskCompletionSummaryProvider 放入您可以解析的 Project.adjustCompletionState 方法中

Rather than passing in a TaskRepository/TaskCompletionSummaryProvider into the Project.adjustCompletionState method you could resolve the dependency at the application layer level.

var project = projectRepository.projectOfId(someProjectId);
var taskCompletionSummary = taskRepository.taskCompletionSummaryOfProject(project.id());
project.adjustCompletionState(taskCompletionSummary);


class Project {
    public void adjustCompletionState(TaskCompletionSummary summary) {
        //The following line could be seen as defensive programming. You could also trust that the application layer is doing it's job correctly. It wouldn't be required at all if a `TaskCompletionSummaryProvider` service would be injected directly instead.
        if (this.id != summary.projectId()) throw new InvalidOperationException('Wrong summary for project');

        if (summary.allCompleted()) this.completionState = ProjectCompletionState.COMPLETED;
        else this.completionState = ProjectCompletionState.inProgress(summary.completionPercentage());
    }
}