首页 > 解决方案 > 如何通过实体内的注入服务访问查找数据?

问题描述

我的应用程序将 DDD 与 .NET Core 和 EF Core 一起使用。我有一些在实体中运行的业务规则,需要根据缓存的公司假期日期列表检查日期。公司假期从数据库加载并由配置有我们的 DI 容器的应用程序服务缓存,因此可以将其注入我们的控制器等。

我无法确定如何将服务注入实体,或者它是否是正确/最佳方法,以便它可以在运行业务规则时获取这些日期。我确实找到了这个似乎展示了一种方法的答案,但我想看看是否有任何其他选项,因为乍一看,这种方式对我来说有点代码味道(向 DbContext 添加一个属性到抓住私有构造函数注入的上下文)。

还有其他方法可以完成这样的事情吗?

标签: dependency-injection.net-coreentity-framework-coredomain-driven-design

解决方案


ORM 类很少是您的域对象。如果您可以从您的域开始并无缝映射到 ORM 而无需基础架构特定的更改或属性,那很好;否则,您需要将域对象与 ORM 对象分开。

您不应将任何服务或存储库注入聚合。聚合应专注于解决方案的命令/事务方面,并使用预加载状态,并应避免通过任何手动机制请求其他状态。应该获取状态并将其交给聚合。

在您的特定情况下,我建议BusinessCalendar在执行某些功能时加载您,然后将其交给您的聚合,例如:

public class TheAggregate
{
    public bool AttemptRegistration(BusinessCalendar calendar)
    {
        if (!calendar.IsWorkingDay(DateTime.Now))
        {
            return false;
        }

        // ... registration code

        return true;
    }

    // or perhaps...

    public void Register(DateTime registrationDate, BusinessCalendar calendar)
    {
        if (!calendar.IsWorkingDay(registrationDate))
        {
            throw new InvalidOperationException();
        }

        // ... registration code
    }
}

对此的另一种看法是让您的域忽略这一点并将负担放在调用代码上。这样,如果您要求域做某事,它就会这样做,因为在某些情况下,可能会在非工作日(在我的简单示例中)进行注册。在这些情况下,应用层负责检查日历是否“正常”注册或在某些情况下覆盖默认行为。这与授权所采用的方法相同。应用层负责授权,域不应该关心这个。如果您可以调用域代码,那么您已被授权这样做。


推荐阅读