用户层:

1.请求应用层获取用户显示的信息

2.发送命令给应用层要求执行某个命令

应用层:

对用户界面提供各种应用功能(包括信息获取与命令执行),应用层不包含业务逻辑,业务层是由应用层调用领域层(领域对象或领域服务)来完成的,应用层是很薄的一层

领域层:

包含领域对象和领域服务,完成系统所需的业务处理,是系统的核心。业务逻辑与仓储接口都在领域层

基础机构层:

包含其他层所需要使用的所有基础服务与技术,比如仓储的实现(与数据打交道)、短消息发送、Json字符串处理

工作单元:

保证聚合间的一致性

通常在领域服务或应用服务中使用工作单元

仓储实现不用考虑数据库事务

一般通过应用层访问仓储,而且是使用领域层定义的仓储接口,具体仓储的实现调用可以通过IOC的机制在应用层通过服务定位器模式找到。

一般不要在领域层访问仓储,如果领域层中的领域对象或领域服务的业务逻辑处理确实需要访问仓储,建议不通过服务定位器的方式在领域层进行服务解析,

而是应该在领域对象或领域服务的构造函数中传入仓储接口,具体是哪个仓储实现,仍然在服务层通过应用模式找到,这样保证服务层只关注业务,而不关注其他方面

一些界面需要获取的查询信息,不应该通过领域对象直接返回给应用服务层,应该在应用 层实现DTO

代码:

   /// <summary>
/// 仓储的接口 维护这个接口里面的状态
/// </summary>
/// <typeparam name="TAggreateRoot"></typeparam>
public interface IRepository<TAggreateRoot> where TAggreateRoot:class, IAggreateRoot
{
void Create(TAggreateRoot aggreateroot);
TAggreateRoot GetByID(Guid id);
List<TAggreateRoot> GetByCondition(Expression<Func<TAggreateRoot, bool>> condition);
void Update(TAggreateRoot aggreateroot);
void Remove(TAggreateRoot aggreateroot);
void RemovdByID(Guid id);
}
/// <summary>
/// 仓储上下文的接口 全部放到上下文中 通过工作单元 一起提交
/// IDisposable 定时释放资源
/// </summary>
public interface IRepositoryContext:IUnitOfWork,IDisposable
{
//创建对象的集合
void RegisterCreate<TAggreateRoot>(TAggreateRoot aggreateroot) where TAggreateRoot : class, IAggreateRoot; //修改
void RegisterUpdate<TAggreateRoot>(TAggreateRoot aggreateroot) where TAggreateRoot : class, IAggreateRoot; //删除
void RegisterRemove<TAggreateRoot>(TAggreateRoot aggreateroot) where TAggreateRoot : class, IAggreateRoot;
Guid ContextID { get; } }
public interface IUnitOfWork
{
void Commit();
void RollBack();
//是否提交
bool Committed { get; set; }
}

仓储上下文:

 public abstract class RepositoryContext : IRepositoryContext, IDisposable
{
//保证线程本地化
private readonly ThreadLocal<Dictionary<Guid, object>> localcreatedics = new ThreadLocal<Dictionary<Guid, object>>(); private readonly ThreadLocal<Dictionary<Guid, object>> localupdatedics = new ThreadLocal<Dictionary<Guid, object>>(); private readonly ThreadLocal<Dictionary<Guid, object>> localremovedics = new ThreadLocal<Dictionary<Guid, object>>(); //是否已经提交
private readonly ThreadLocal<bool> localcommitted = new ThreadLocal<bool>(()=>true); public virtual void RegisterCreate<TAggreateRoot>(TAggreateRoot aggreateroot) where TAggreateRoot :
class, IAggreateRoot
{
if (aggreateroot.Id.Equals(Guid.Empty))
{
throw new AggregateException("聚合根ID不能为空");
}
if (localcreatedics.Value.ContainsKey(aggreateroot.Id))
{
throw new InvalidOperationException("新创建的领域对象已经存在在集合中");
}
//向集合总提交 聚合根的id 和聚合根
localcreatedics.Value.Add(aggreateroot.Id, aggreateroot);
//标注为未提交
localcommitted.Value = false;
} public virtual void RegisterUpdate<TAggreateRoot>(TAggreateRoot aggreateroot) where TAggreateRoot :
class, IAggreateRoot
{
if (aggreateroot.Id.Equals(Guid.Empty))
{
throw new AggregateException("聚合根ID不能为空");
}
if (localupdatedics.Value.ContainsKey(aggreateroot.Id))
{
throw new InvalidOperationException("更新的领域对象已经存在在集合中");
}
if (localremovedics.Value.ContainsKey(aggreateroot.Id))
{
throw new InvalidOperationException("领域对象正在被更新,不能删除");
}
localremovedics.Value.Add(aggreateroot.Id, aggreateroot);
localcommitted.Value = false;
} public virtual void RegisterRemove<TAggreateRoot>(TAggreateRoot aggreateroot) where TAggreateRoot :
class, IAggreateRoot
{
if (aggreateroot.Id.Equals(Guid.Empty))
throw new ArgumentException("聚合根ID不能为空");
if (localremovedics.Value.ContainsKey(aggreateroot.Id))
throw new InvalidOperationException("删除的领域对象已经存在在集合中");
if (localupdatedics.Value.ContainsKey(aggreateroot.Id))
throw new InvalidOperationException("领域对象正在被更新,不能删除");
localremovedics.Value.Add(aggreateroot.Id, aggreateroot);
localcommitted.Value = false;
} public Guid ContextID
{
get
{
return Guid.NewGuid();
}
} public abstract void Commit(); /// <summary>
/// 提交的属性
/// </summary>
public bool Committed
{
get { return localcommitted.Value; }
set { localcommitted.Value = value; }
} /// <summary>
/// 释放资源
/// </summary>
public virtual void Dispose()
{
localcreatedics.Dispose();
localupdatedics.Dispose();
localremovedics.Dispose();
localcommitted.Dispose();
} //在仓储中具体实现
public abstract void RollBack();
}

具体的实现 :

/// <summary>
/// 仓储类的实现
/// </summary>
public class EFRepository<TAggreateRoot> : EFRepositoryContext, IRepository<TAggreateRoot>
where TAggreateRoot :class,IAggreateRoot
{
public void Create(TAggreateRoot aggreateroot)
{
base.RegisterCreate(aggreateroot);
} public List<TAggreateRoot> GetByCondition(Expression<Func<TAggreateRoot, bool>> condition)
{
throw new NotImplementedException();
} public TAggreateRoot GetByID(Guid id)
{
throw new NotImplementedException();
} public void RemovdByID(Guid id)
{
throw new NotImplementedException();
} public void Remove(TAggreateRoot aggreateroot)
{
base.RegisterRemove(aggreateroot);
} public void Update(TAggreateRoot aggreateroot)
{
base.RegisterUpdate(aggreateroot);
}
}

仓储上线文的实现:

/// <summary>
/// 仓储上下文的实现
/// </summary>
public class EFRepositoryContext : RepositoryContext
{
public override void RegisterCreate<TAggreateRoot>(TAggreateRoot aggreateroot)
{
base.RegisterCreate<TAggreateRoot>(aggreateroot);
Committed = false;
}
public override void RegisterRemove<TAggreateRoot>(TAggreateRoot aggreateroot)
{
base.RegisterRemove<TAggreateRoot>(aggreateroot);
Committed = false;
}
public override void RegisterUpdate<TAggreateRoot>(TAggreateRoot aggreateroot)
{
base.RegisterUpdate<TAggreateRoot>(aggreateroot);
Committed = false;
}
public override void Commit()
{
Committed = true;
} public override void RollBack()
{
Committed = true;
} public override void Dispose()
{
base.Dispose();
}
}

判断ID:

 public interface  IEntity
{
Guid Id { get; }
}
public  interface IAggreateRoot:IEntity
{
}
 public abstract class AggreateRoot:Entity
{
}
 public abstract class Entity : IEntity
{
public Guid Id
{
get
{
var id = Guid.NewGuid();
return id;
}
} /// <summary>
/// 比较两个对象
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
//判断两个实列是否相等
if (ReferenceEquals(this, obj))
{
return true;
}
//判断ID是否相等
return this.Id == (obj as IEntity).Id;
} public override int GetHashCode()
{
return this.Id.GetHashCode();
}
}

DDD领域模型企业级系统(二)的更多相关文章

  1. DDD领域模型企业级系统(一)

    领域模型的基本构造块: 1.实体(Entity):有业务生命周期,使用标识进行跟踪. 2.值对象(Value Object):无业务生命周期,用来描述实体. 3.服务(Service):无状态的行为类 ...

  2. DDD领域模型企业级系统Unity(五)

    添加程序集: 写一个接口: public interface IPlayer { void Play(); } 两个实现类: public class NewPlay : IPlayer { publ ...

  3. DDD领域模型企业级系统Linq的CRUD(四)

    建造一个Product Module类: ProductDBContextDataContext dbcontext = new ProductDBContextDataContext(); publ ...

  4. DDD领域模型企业级系统(三)

    相关代码: public static void ShowArray() { //数据源 int[] arrayas = new int[] { 1, 2, 3, 4 }; //创建查询 var qu ...

  5. DDD领域模型和充血对象

    DDD领域模型 官方说法 领域驱动设计,它是对面向对象的的分析和设计(OOAD,Object Orient Analysis Design)的一个补充,对技术框架进行了分层规划,同时对每个类进行了策略 ...

  6. Win7系统安装Centos7.0双系统(二)

    4.6语言选择

  7. Epicor系统二次开发

    Epicor系统二次开发 一.获取或修改界面EpiDataView的字段数据(Get EpiDataView data) C# EpiDataView edv = (EpiDataView)oTran ...

  8. go语言打造个人博客系统(二)

    go语言打造个人博客系统(二)   在上篇文章go语言打造个人博客系统(一)中,我们了解了go语言的优点和go语言的数据库操作,本次我们会完成博客系统的后端开发. 博客系统后端接口开发 路由测试 ht ...

  9. UGUI的优点新UI系统二 直观、易于使用

    UGUI的优点新UI系统二 直观.易于使用   对于UI控件,开发者可以直接使用鼠标在Scene视图里编辑它们的大小.位置和旋转角度,而无需编写任何代码,以Button为例,如图1-3.图1-4和图1 ...

随机推荐

  1. IL指令集

    声明: 1.本指令集搜集自网上各个论坛帖子,欢迎补充 IL指令集 名称 说明     Add 将两个值相加并将结果推送到计算堆栈上.     Add.Ovf 将两个整数相加,执行溢出检查,并且将结果推 ...

  2. UDP ------ UDP IPPROTO_UDPLITE 参数

    介绍 传统的 UDP 通信对整个报文进行校验 UDP-LITE 通信则可以设置校验的长度,适用于可以接受轻微的报文内容出错,比如视频数据:传统的 UDP 由于对整个报文校验,一旦出现报文数据出错就会被 ...

  3. vhost配置

    server { listen ; server_name local.*****.com; index index.html index.htm index.php; root /home/wwwr ...

  4. P2042 [NOI2005]维护数列 && Splay区间操作(四)

    到这里 \(A\) 了这题, \(Splay\) 就能算入好门了吧. 今天是个特殊的日子, \(NOI\) 出成绩, 大佬 \(Cu\) 不敢相信这一切这么快, 一下子机房就只剩我和 \(zrs\) ...

  5. 《剑指offer》面试题39 二叉树的深度(java)

    摘要: 今天翻到了<剑指offer>面试题39,题目二中的解法二是在函数的参数列表中通过指针的方式进行传值,而java是没有指针的,所以函数要进行改造.然而我翻了下别人的java版本(我就 ...

  6. Challenge 18

    Challenge 18给你一个长度为 n 的非负整数序列 a 和 m 个询问 l, r, p, k,表示询问在 a[l .. r] 中 a[i]%p=k 的 i 的个数. 思路: 将序列分为根号n块 ...

  7. [洛谷P3292] [SCOI2016]幸运数字

    洛谷题目链接:[SCOI2016]幸运数字 题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城 ...

  8. IntelliJ IDEA中Java类注释

    打开Idea,依次选择File-->Settings-->Editor-->File and CodeTemplates ,右侧tab选项卡点击Includes,选择File Hea ...

  9. 同一个IIS绑定多个Htts 站点问题

    默认情况一个服务器的IIS只能绑定一个HTTPS也就是443端口 要实现多个站点对应HTTPS只能更改IIS配置 地址:C:Windowssystem32inetsrvconfigapplicatio ...

  10. 【leetcode 简单】 第七十五题 第一个错误的版本

    你是产品经理,目前正在带领一个团队开发新的产品.不幸的是,你的产品的最新版本没有通过质量检测.由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的. 假设你有 n 个版本 [1, ...