域驱动开发Entitiy基类

时间:2015-12-17 18:58:12

标签: c# .net domain-driven-design

我很抱歉,如果这个问题是微不足道的,而且已经无法解决了。我一直在寻找一个anwser,但我能找到的只是给定情况的图像和UML而没有解释。我已经开始阅读.NET Domain-Driven-Design书籍了,我发现自己在一开始就遇到了一堵砖墙。我的问题是作者建议为实体创建一个基类,这个基类放在Infrasturcture层。该类将由Domain中的所有Entity类继承。这似乎非常罕见并且反直觉,至少对我而言。所以我试着按照这本书,但我不明白为什么这是一个好主意,因为我害怕在项目的未来发展中循环依赖,并且无法理解为什么要实体基地class在域之外。谢谢。

编辑:

我害怕循环依赖,因为在实施阶段之前的章节中,作者描述了依赖性的下降。从UI开始 - >应用层 - >基础架构层的域不引用任何人,但每个人都引用了基础架构层。所以我很难理解域为什么要引入Infastructure呢?关于DDD(我假设),域应该独立于其他层。所以我只是想问域名 - >基础设施依赖是常见的事情,还是应该有更好/更清洁的解决方案? 我正在阅读的这本书在C#Problem-Design-Solution

中称为.NET域驱动设计

编辑基于架构描述:

此链接提供描绘手头设计架构的图像。我正在遵循的书中提供了相同的图像。 https://ajlopez.wordpress.com/2008/09/12/layered-architecture-in-domain-driven-design/。感谢您的反馈和答案。

4 个答案:

答案 0 :(得分:1)

如果你有一个将基础架构置于底层的分层架构,那么将基础类放在基础架构层中只是一个好主意 - 这不是大多数架构现在所做的。

所以我建议不要这样做。将实体基类型放在域层中。

没人会问"这是什么领域概念?"如果你说得恰当的话。确保该类是抽象的并且正确记录。这将进一步澄清情况。

使用DDD,将域名置于" center" (例如,六边形架构)通常比具有底层基础设施的传统分层架构更合适。这种体系结构的重要特性是所有依赖关系都指向内部,即面向域。

答案 1 :(得分:0)

它被称为layer supertype并且是一种常见模式。

一般来说,隐藏"方便。公共基类中域实体所需的所有基础结构代码(例如持久层所需的数据库ID,而不是域中所需的数据库ID),以便实际的域类不会受到基础结构代码的污染。

我同意你应该避免循环依赖。但是,您不需要将基类实际移动到单独的项目(以避免循环依赖)。我想作者的意思是语义上这个基类属于基础结构层,因为它包含数据库ID。

答案 2 :(得分:0)

如果您遵循onion架构的原则,那么域是中间层(没有依赖关系),基础架构是外层(具有依赖关系)。

您不希望您的域模型依赖于基础架构问题,因此这意味着您的基类绝对属于域层。我们的想法是,基础设施的任何变化(或任何技术变更)都不会影响域/业务/应用层。

此外,尝试针对接口进行编程,在运行时为其注入具体实现。这也避免了中间层与基础设施问题的任何耦合。

答案 3 :(得分:0)

域驱动开发体系结构是一种分层设计,当您需要将业务规则(用户需求)与项目的其余部分分开时,它可以非常好用。开发中的中心域

在实施DDD架构时,通常会看到 Dependency Injection Inversion of Control 等概念。 下面的示例是将Domain置于应用程序中心的众多方法之一,它只是为了让您记住一些事情。

  • :包含属于业务规则的接口和类。 (它没有实现任何东西,每个方法都通过基础设施级别的依赖注入传递)。
  • 基础架构:实现在域级别创建的所有接口。该层负责设计所有" techological"应用程序的行为。 此图层引用域

  • 演示文稿:这是用户界面。连接域和依赖注入层。 此层可以查看依赖注入和域

  • 依赖注入:解决依赖性问题。它返回参数传递的接口实现。 此层可以查看基础架构和域。

如下所示:(我使用 C#

域名级别:      如您所见,该方法没有实际的实现。只有依赖项调用才能找到接口IFight的实现。

public class Samurai
    {
        public void Attack()
        {
            /*There are no class coupling here. 'Solve' receives an Interface as 
              parameter and do its job in order to return an object of the instance
            and it calls the method Attack*/
            Dependencies.Solver<IFight>().Attack(); //Forget about this right now. You will understand it as the post goes on.
       }
    }

然后我们需要实现一个在基础架构级别实现的接口。

 public interface IFight
    {
        /*This interface is declared at the domain, altought, it is 
        implemented at infrastructure layer.*/
        void Attack();
    }

要使依赖项注入有效,需要在域级别实现它。

public class Dependencies
    {
        private static ISolve _solver;
        public static ISolve Solver
        {
            get
            {
                if (_solver == null)
                    throw new SolverNotConfiguratedException();
                return _solver;
            }
            set
            {
                _solver = value;
            }
        }
    }

还有一个解决者:

public interface ISolve
{
    //This interface will be implemented at DependencyInjection layer.
    T Solve<T>();
}

基础设施级别:

接口的实现

   public class Fight : IFight
    {
        public void Attack()
        {
            Console.WriteLine("Attacking...");
        }
    }

依赖注入级别:

现在设置注射

非常重要
public class Solver : ISolve
    {
        private UnityContainer _container = new UnityContainer();
        public Solver()
        {
            /* Using Unity "Framework to do Dependency Injection" it is possible do register a type.
             When the method 'Solve' is called, the container looks for a implemented class that inherits
             methods from a certain interface passed by parameter and returns an instantiated object.
             */
            _container.RegisterType<IFight,Fight>();
        }

        //This is where the magic happens
        public T Solve<T>()
        {
            return _container.Resolve<T>();
        }

Samurai班的依赖性解释:

//We are making a request of an interface implementation for Dependency 
Solver. The Domain does not know who what class is doing it and how. 
Dependencies.Solver<IFight>().Attack();

演示级别:

Samurai samurai = new Samurai()
samurai.Attack();

结论:

我们可以看到域名是实施的中心,并且每个业务规则都可以在该级别轻松看到白色的技术内容。