DDD领域模型企业级系统(二)
用户层:
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领域模型企业级系统(二)的更多相关文章
- DDD领域模型企业级系统(一)
领域模型的基本构造块: 1.实体(Entity):有业务生命周期,使用标识进行跟踪. 2.值对象(Value Object):无业务生命周期,用来描述实体. 3.服务(Service):无状态的行为类 ...
- DDD领域模型企业级系统Unity(五)
添加程序集: 写一个接口: public interface IPlayer { void Play(); } 两个实现类: public class NewPlay : IPlayer { publ ...
- DDD领域模型企业级系统Linq的CRUD(四)
建造一个Product Module类: ProductDBContextDataContext dbcontext = new ProductDBContextDataContext(); publ ...
- DDD领域模型企业级系统(三)
相关代码: public static void ShowArray() { //数据源 int[] arrayas = new int[] { 1, 2, 3, 4 }; //创建查询 var qu ...
- DDD领域模型和充血对象
DDD领域模型 官方说法 领域驱动设计,它是对面向对象的的分析和设计(OOAD,Object Orient Analysis Design)的一个补充,对技术框架进行了分层规划,同时对每个类进行了策略 ...
- Win7系统安装Centos7.0双系统(二)
4.6语言选择
- Epicor系统二次开发
Epicor系统二次开发 一.获取或修改界面EpiDataView的字段数据(Get EpiDataView data) C# EpiDataView edv = (EpiDataView)oTran ...
- go语言打造个人博客系统(二)
go语言打造个人博客系统(二) 在上篇文章go语言打造个人博客系统(一)中,我们了解了go语言的优点和go语言的数据库操作,本次我们会完成博客系统的后端开发. 博客系统后端接口开发 路由测试 ht ...
- UGUI的优点新UI系统二 直观、易于使用
UGUI的优点新UI系统二 直观.易于使用 对于UI控件,开发者可以直接使用鼠标在Scene视图里编辑它们的大小.位置和旋转角度,而无需编写任何代码,以Button为例,如图1-3.图1-4和图1 ...
随机推荐
- 线程属性API
数据类型:pthread_attr_t 操作API: // 初始化线程属性 int pthread_attr_init(pthread_attr_t *attr);// 初始化为系统支持的所有属性的默 ...
- 【Asp.net入门01】动态网站基础知识
本节将介绍: 网站搭建流程 动态网站相关基础概念 网页的访问原理 使用浏览器访问网站是我们几乎天天在做的事情.以前我们只需要关注网页内容,作为网站开发人员,从现在开始我们要关注更深层次的东西了. 1. ...
- SQL复杂语句查询练习
--复杂查询练习 -- 1 .列出所有员工的年工资,按年薪从低到高排序. SELECT (SAL+NVL(COMM,0))*12 INCOME FROM EMP ORDER BY INCOME; -- ...
- Python 不定参数函数
1. 元组形式 def test1(*args): print('################test1################') print(type(args)) print(arg ...
- 项目经验总结-twice
1.尽量指定类.方法的final修饰符 带有final修饰符的类是不可派生的.在Java核心API中,有许多应用final的例子,例如java.lang.String,整个类都是final的.为类指定 ...
- vue相关安装命令
安装cnpm npm install cnpm -g --registry=https://registry.npm.taobao.org
- python---基础知识回顾(十)进程和线程(进程)
前戏:进程和线程的概念 若是学过linux下的进程,线程,信号...会有更加深刻的了解.所以推荐去学习下,包括网络编程都可以去了解,尤其是对select,poll,epoll都会有更多的认识. 进程就 ...
- NOI2006 最大获利(最大权闭合子图)
codevs 1789 最大获利 2006年NOI全国竞赛 时间限制: 2 s 空间限制: 128000 KB 题目描述 Description 新的技术正冲击着手机通讯市场,对于各大运营商来 ...
- 从零搭建SSM框架(一)搭建工程
工程结构 一.cnki-parent 1.新建maven project 2.pom.xml <project xmlns="http://maven.apache.org/POM/ ...
- codeforces997C Sky full of stars
传送门:http://codeforces.com/problemset/problem/997/C [题解] 注意在把$i=0$或$j=0$分开考虑的时候,3上面的指数应该是$n(n-j)+j$ 至 ...