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 ...
随机推荐
- bzoj 4332 FFT型的快速幂(需要强有力的推导公式能力)
有n个小朋友,m颗糖,你要把所有糖果分给这些小朋友. 规则第 i 个小朋友没有糖果,那么他之后的小朋友都没有糖果..如果一个小朋友分到了 xx 个糖果,那么的他的权值是 f(x) = ox^2 + ...
- python学习(21) smtp发送邮件
原文链接: https://www.jianshu.com/p/369ec15bfe22 本文介绍python发送邮件模块smtplib以及相关MIME模块.smtplib用于生成邮件发送的代理,发送 ...
- centos禁用ipv6
两步完成 vi /etc/sysctl.conf net.ipv6.conf.all.disable_ipv6=1sysctl -p /etc/sysctl.conf
- windows10 conda2 使用caffe训练训练自己的数据
首先得到了https://blog.csdn.net/gybheroin/article/details/72581318系列博客的帮助.表示感激. 关于安装caffe已在之前的博客介绍,自用可行,h ...
- matlab和C语言实现最小二乘法
参考:https://blog.csdn.net/zengxiantao1994/article/details/70210662 Matlab代码: N = ; x = [ ]; y = [ ]; ...
- OC中线程安全的单例
@implementation MySingleton + (instancetype)sharedInstance { static MySingleton* instance = nil; sta ...
- Mongodb 笔记02 创建、更新和删除文档
创建.更新和删除文档 1. 插入并保存: 1). 单条插入,insert : db.foo.insert({"bar":"baz"}) 2). ...
- Python设计模式(六大)
1.外观模式(Facade) 一层一层向上封装,灵活性会降低,功能完成度高,和python的模块比较像,但对于封装好了的类,将会变得很简单,简洁. 2.六大设计原则 单一职责原则 (Single Re ...
- 数据结构编程实验——chapter8-采用树结构的非线性表编程
关于树结构的非线性表编程在数据结构中可以说占据了半壁江山,其中涉及的知识点繁杂,但也是数据结构体现运算优化的核心所在,下面我们将较为初步且系统得讨论数据结构中一系列有关树的表示. 首先我们再次明确树的 ...
- Linux部署node环境
# wget https://nodejs.org/dist/v8.11.4/node-v8.11.4-linux-x64.tar.xz# tar -axvf node-v8.11.4-linux-x ...