【问题标题】:Dependency between Application Layer and Domain Layer应用层和领域层之间的依赖关系
【发布时间】:2026-01-08 15:40:01
【问题描述】:

我想减少ApplicationLayer和DomainLayer之间的连接。考虑一下我在域项目中创建了一个 AggregateRoot。如果我直接从 Application 引用 Domain 就可以了。
但是我想使用接口而不是实现,所以我创建了Domain.Contract来保留Domain项目的接口和合同!Domain对这个项目有一个参考来实现接口。如何在应用层使用这个合约。换句话说:

Domain 有 Domain.Contract 的引用。
Application 有 Domain.Contract 的引用。

在域项目中,我有卡片类
在 Domain.Contract 项目中,我有 ICard 接口 在应用程序项目中,我只想引用 Domain.contract 并且我有创建 Card 的 CommandHandlers 方法

CommandHandlerMethod()
{
   var card = ICard?!!! //What should I do here?
   repository.Save(card);
}

我发现的一种方法是使用工厂。但是工厂现在应该是接口和实现的类,它们在不同的项目中。如果我在 Domain.contract 项目中使用工厂,它将导致引用循环。如果我在 Domain 项目中使用 Factory,应用程序项目将如何使用它?!

【问题讨论】:

  • 你想完成什么? ICard 是否包含任何需要抽象的Volatile behavior,还是仅仅是一个数据契约?不要在Contract 中定义ICard,而是考虑将Card 本身移动到Contract
  • @Steven 感谢您的关注,我想通过使用域接口或仅域的工厂来松散应用层和域层之间的耦合。在我看来,应用程序不应该知道域将如何构建自己。就我而言,接口只是数据合约。
  • 亲爱的@Steven,您现在可以在我的project 的自述文件中看到依赖项

标签: dependency-injection dependencies domain-driven-design


【解决方案1】:

据我了解,您可以在“Domain.Contracts”中定义 IFactory 接口并将其实现留在“Domain”中。现在应用程序层将只知道“Do​​main.Contracts”,并且 IFactory 将被注入“ApplicationService”对象。事实上,“工厂”不会是静态类“ 你的代码应该是这样的:

public class AppService
{
    public IFactory Factory { get; set; }
    public AppService(IFactory factory)
    {
       Factory = factory;
    }
    public void Handle(CreateCommand cmd)
    {
        var card = Factory.Create(cmd.Prop1);
        repo.Add(card);
    }
}

【讨论】:

  • 尊敬的 Abbasi 先生,您现在可以在我的 project 的自述文件中查看依赖项
【解决方案2】:

您的工厂应该在您的域项目中实现并且应该是完全公开的。

它的目的是为应用层构建一个ICard,而不需要应用层直接与Card交互。如果与工厂部署在同一项目中,则 Card 上的构造函数可以是内部的。

工厂不应在合同中。合约应该只包含接口,而不是任何实现,包括工厂。

是的,工厂必须知道接口和实现的类。这就是它的工作……创建接口的具体实现。

参考资料:

  • 应用程序 > Domain.Contract
  • 应用 > 域
  • 域 > Domain.Contract

域合同

public interface ICard
{
    public string Value { get; }
    public void SetValue(string value);
}

public class Card : ICard
{
    string Value { get; private set; }

    public void SetValue(string value)
    {
        Value = value;
    }

    // INTERNAL.  Can only be created by the factory, not the application
    internal Card(string value)
    {
        SetValue(value);
    }
}

public static class CardFactory
{
    public static ICard CreateCard(string value)
    {
        return new Card(value);
    }
}

应用程序

ICard card = CardFactory.CreateCard("Ace of Spades");
repo.Add(card);

【讨论】:

  • 感谢您回答我的问题。我的问题的要点是从应用程序中删除域引用。我在一些小组中提问。一位建议将工厂接口注入应用程序类。另一个介绍Composition Root。我认为组合根可以解决我的问题,只是尝试编写代码,您怎么看?
  • 是的,如果您的目标是让整个域模型在抽象之后可替换,那么注入 Factory 接口就可以了。无论有没有专用的微服务/模块组合根,它都可以工作。
  • 亲爱的 Neil,您现在可以在我的 project 的自述文件中查看依赖项
最近更新 更多