领域驱动设计案例之领域层框架搭建

根据前面对领域驱动设计概念以及一些最佳实践的理解,领域模型是系统最核心的部分,我们还是采用前面销售订单的例子,这个案例系统的核心构建就从领域层开始。领域层框架搭建主要完成两个任务:

1.领域模型的建立,聚合与聚合根的确定,关系的确定。

2.建立支持DDD理论的领域层接口。

这里先上代码图,再详细讲每个部分的主要功能:

1.Model中主要确定了领域对象,聚合与聚合根,关联关系等,我们这里采用的是EF 的Model First建模,你也可以采取Code First。如下图:

2.Aggreate中主要定义了两个接口,一个是IEntity,一个是IAggreateRoot,分别表示实体与聚合根。

using System;

namespace Order.Domain.Aggreate
{
    public interface IEntity<TIdentity>
    {
        TIdentity BusinessId { get; set; }
        Guid Id { get; }
    }
}
namespace Order.Domain.Aggreate
{
    public interface IAggreateRoot<TIdentity>:IEntity<TIdentity>
    {
    }
}

3.Repository中主要定义了IRepository与IRepositoryContext接口。

将IRepository接口定义在领域层的主要目的是:

1)领域层不应该直接依赖于仓储实现:如果领域层依赖于仓储实现,一是技术绑定太紧密,二是仓储要对领域对象作操作,会造成循环依赖。

2)将接口定义在领域层,减少技术架构依赖,应用层或领域层要使用某个仓储实现时,通过依赖注入的方式将仓储实现注射到应用层或领域层,具体IOC在使用时对应用层与领域层的建议见前面的文章。

定义IRepositoryContext接口的主要目的是:因为我们采用的持久化机制是EF,EF是通过DBContext来管理数据操作的事务,一般是针对单实体的。通常我们的业务需要持久化整个聚合的多个实体或通过领域服务或应用服务持久化多个聚合,多个实体或聚合在业务上需要保持一致性,为了达到这个目的,我们引入了工作单元模式与定义了仓储上下文,通过仓储上下文来管理操作的多个实体或多个聚合中的实体,然后通过工作单元模式统一提交来保证事务,从而保证业务的一致性。

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Security.Principal;
using Order.Domain.Aggreate;

namespace Order.Domain.Repository
{
    public interface IRepository<TAggreateRoot,TIdentity> where TAggreateRoot:class,IAggreateRoot<TIdentity>
    {
        #region 创建对象
        void Create(TAggreateRoot aggreateroot);
        #endregion
        #region 重建对象
        TAggreateRoot GetbyId(Guid id);
        TAggreateRoot GetbyIdentity(TIdentity identity);
        List<TAggreateRoot> GetbyCondition(Expression<Func<TAggreateRoot, object>> condition);
        #endregion
        #region 更新对象
        void Update(TAggreateRoot aggreateroot);
        #endregion
        #region 销毁对象
        void Remove(TAggreateRoot aggreateroot);
        void RemoveById(Guid id);
        void RemoveByIdentity(IIdentity identity);
        #endregion
    }
}
namespace Order.Domain.Repository
{
    public interface IUnitOfWork
    {
        bool Committed { get; }
        void Commit();
        void RollBack();
    }
}
using System;

namespace Order.Domain.Repository
{
    public interface IRepositoryContext:IUnitOfWork,IDisposable
    {
        Guid ContextId { get; }
        /// <summary>
        /// 在事务上下文中标记聚合根为创建状态
        /// </summary>
        /// <typeparam name="TAggreateRoot"></typeparam>
        /// <param name="aggreateroot"></param>
        void RegisterCreate<TAggreateRoot>(TAggreateRoot aggreateroot);
        /// <summary>
        /// 在事务上下文中标记聚合根为更改状态
        /// </summary>
        /// <typeparam name="TAggreateRoot"></typeparam>
        /// <param name="aggreateroot"></param>
        void RegisterUpdate<TAggreateRoot>(TAggreateRoot aggreateroot);
        /// <summary>
        /// 在事务上下文中标记聚合根为销毁状态
        /// </summary>
        /// <typeparam name="TAggreateRoot"></typeparam>
        /// <param name="aggreateroot"></param>
        void RegisterRemove<TAggreateRoot>(TAggreateRoot aggreateroot);

    }
}
时间: 2024-11-02 23:27:05

领域驱动设计案例之领域层框架搭建的相关文章

领域驱动设计案例之领域层实体与聚合根实现

在领域层中,可以实现实体与聚合根的业务逻辑,在实现业务逻辑之前,我们首先要确定实体和聚合根的一些基本行为,比如判断实体是否相等.关于领域对象的具体业务逻辑实现,因为涉及到要与数据库交互,所以等看完仓储的实现后,再实现领域对象的业务逻辑. using System; using Order.Domain.Aggreate; namespace Order.Domain.Model { public abstract class Entity : IEntity { private Guid id

领域驱动设计案例之业务实现1

业务上主要实现产品的创建,客户的创建.下订单的业务,这里主要演示领域驱动设计的思想与一些最佳实践如何体现到领域的实现中,代码中的一些 Bug或瑕疵不用太过理会. 在DDD.Doman项目中实现相应的聚合根.实体与值对象. 这篇文章主要实现客户的创建,因为通过Model-First已经建立了领域模型,所以我们建立分部类来实现领域对象的业务逻辑部分. public partial class Customer:AggreateRoot { private IRepository<Customer>

[.NET领域驱动设计实战系列]专题二:结合领域驱动设计的面向服务架构来搭建网上书店

一.前言 在前面专题一中,我已经介绍了我写这系列文章的初衷了.由于dax.net中的DDD框架和Byteart Retail案例并没有对其形成过程做一步步分析,而是把整个DDD的实现案例展现给我们,这对于一些刚刚接触领域驱动设计的朋友可能会非常迷茫,从而觉得领域驱动设计很难,很复杂,因为学习中要消化一个整个案例的知识,这样未免很多人消化不了就打退堂鼓,就不继续研究下去了,所以这样也不利于DDD的推广.然而本系列可以说是刚接触领域驱动设计朋友的福音,本系列将结合领域驱动设计的思想来一步步构建一个网

领域驱动设计案例之仓储顶层实现

在业务中,我们会涉及到对象的创建.重建.更新.销毁等操作,这些操作通常需要持久化到数据库中,我们通过仓储来实现对数据的访问 1.首先我们要实现仓储上下文,仓储上下文主要是维护一些创建.更新.销毁的对象列表,未来可以实现批量持久化,从而保持多实体与多聚合的事务,从而实现内部一致性和外部一致性: using Order.Domain.Aggreate; using Order.Domain.Repository; using System; using System.Collections.Gene

领域驱动设计的面向服务架构

[.NET领域驱动设计实战系列]专题二:结合领域驱动设计的面向服务架构来搭建网上书店 一.前言 在前面专题一中,我已经介绍了我写这系列文章的初衷了.由于dax.net中的DDD框架和Byteart Retail案例并没有对其形成过程做一步步分析,而是把整个DDD的实现案例展现给我们,这对于一些刚刚接触领域驱动设计的朋友可能会非常迷茫,从而觉得领域驱动设计很难,很复杂,因为学习中要消化一个整个案例的知识,这样未免很多人消化不了就打退堂鼓,就不继续研究下去了,所以这样也不利于DDD的推广.然而本系列

EntityFramework之领域驱动设计实践

EntityFramework之领域驱动设计实践 - 前言 EntityFramework之领域驱动设计实践 (一):从DataTable到EntityObject EntityFramework之领域驱动设计实践 (二):分层架构 EntityFramework之领域驱动设计实践 (三):案例:一个简易的销售系统 EntityFramework之领域驱动设计实践 (四):存储过程 - 领域驱动的反模式 EntityFramework之领域驱动设计实践 (五):聚合 EntityFramewor

Re:从零开始的领域驱动设计

领域驱动的火爆程度不用我赘述,但是即便其如此得耳熟能详,但大多数人对其的认识,还只是停留在知道它的缩写是DDD,知道它是一种软件思想,或者知道它和微服务有千丝万缕的关系.Eric Evans对DDD的诠释是那么地惜字如金,而我所认识的领域驱动设计的专家又都是行业中的资深前辈,他们擅长于对软件设计进行高屋建瓴的论述,如果没有丰富的互联网从业经验,是不能从他们的分享中获取太多的营养的,可以用曲高和寡来形容.1000个互联网从业者,100个懂微服务,10个人懂领域驱动设计. 可能有很多和我一样的读者,

NET 领域驱动设计实战系列总结

NET 领域驱动设计实战系列总结 一.引用 其实在去年本人已经看过很多关于领域驱动设计的书籍了,包括Microsoft .NET企业级应用框架设计.领域驱动设计C# 2008实现.领域驱动设计:软件核心复杂性应对之道.实现领域驱动设计和Asp.net 设计模式等书,但是去年的学习仅仅限制于看书,当时看下来感觉,领域驱动设计并没有那么难,并且感觉有些领域驱动设计的内容并没有好的,反而觉得有点华而不实的感觉,所以去年也就放弃了领域驱动设计系列的分享了,但是到今年,在博客园看到还是有很多人写领域驱动的

领域驱动设计和实践

软件系统面向对象的设计思想可谓历史悠久,20世纪70年代的Smalltalk可以说是面向对象语言的经典,直到今天我们依然将这门语言视为面向对象语言的基础.随着编程语言和技术的发展,各种语言特性层出不穷,面向对象是大部分语言的一个基本特性,像C++.Java.C#这样的静态语言,Ruby.Python这样的动态语言都是面向对象的语言. 但是面向对象语言并不是银弹,如果开发人员认为使用面向对象语言写出来的程序本身就是面向对象的,那就大错特错了,实际开发中,大量的业务逻辑堆积在一个巨型类中的例子屡见不