DDD领域驱动设计之领域基础设施层
1、DDD领域驱动设计实践篇之如何提取模型
2、DDD领域驱动设计之聚合、实体、值对象
其实这里说的基础设施层只是领域层的一些接口和基类而已,没有其他的如日子工具等代码,仅仅是为了说明领域层的一些基础问题
1、领域事件简单实现代码,都是来至ASP.NET设计模式书中的代码
namespace DDD.Infrastructure.Domain.Events
{public interface IDomainEvent{}
}
namespace DDD.Infrastructure.Domain.Events
{public interface IDomainEventHandler<T> : IDomainEventHandlerwhere T : IDomainEvent{void Handle(T e);}public interface IDomainEventHandler{}}
namespace DDD.Infrastructure.Domain.Events
{public interface IDomainEventHandlerFactory{IEnumerable<IDomainEventHandler<T>> GetDomainEventHandlersFor<T>(T domainEvent)where T : IDomainEvent;}}
namespace DDD.Infrastructure.Domain.Events
{public class StructureMapDomainEventHandlerFactory : IDomainEventHandlerFactory{public IEnumerable<IDomainEventHandler<T>> GetDomainEventHandlersFor<T>(T domainEvent) where T : IDomainEvent{return ObjectFactory.GetAllInstances<IDomainEventHandler<T>>();}}}
namespace DDD.Infrastructure.Domain.Events
{public static class DomainEvents{public static IDomainEventHandlerFactory DomainEventHandlerFactory { get; set; }public static void Raise<T>(T domainEvent) where T : IDomainEvent{var handlers = DomainEventHandlerFactory.GetDomainEventHandlersFor(domainEvent);foreach (var item in handlers){item.Handle(domainEvent);}}}
}
2、领域层接口代码,很多都是来至MS NLayer代码和google code
namespace DDD.Infrastructure.Domain
{public interface IEntity<out TId>{TId Id { get; }}
}
namespace DDD.Infrastructure.Domain
{public interface IAggregateRoot : IAggregateRoot<string>{}public interface IAggregateRoot<out TId> : IEntity<TId>{}
}
namespace DDD.Infrastructure.Domain
{public abstract class EntityBase : EntityBase<string>{protected EntityBase():this(null){}protected EntityBase(string id){this.Id = id;}public override string Id{get{return base.Id;}set{base.Id = value;if (string.IsNullOrEmpty(this.Id)){this.Id = EntityBase.NewId();}}}public static string NewId(){return Guid.NewGuid().ToString("N");}}public abstract class EntityBase<TId> : IEntity<TId>{public virtual TId Id { get;set;}public virtual IEnumerable<BusinessRule> Validate(){return new BusinessRule[] { };}public override bool Equals(object entity){return entity != null&& entity is EntityBase<TId>&& this == (EntityBase<TId>)entity;}public override int GetHashCode(){return this.Id.GetHashCode();}public static bool operator ==(EntityBase<TId> entity1, EntityBase<TId> entity2){if ((object)entity1 == null && (object)entity2 == null){return true;}if ((object)entity1 == null || (object)entity2 == null){return false;}if (entity1.Id.ToString() == entity2.Id.ToString()){return true;}return false;}public static bool operator !=(EntityBase<TId> entity1, EntityBase<TId> entity2){return (!(entity1 == entity2));}}}
namespace DDD.Infrastructure.Domain
{public interface IRepository<TEntity> : IRepository<TEntity, string>where TEntity : IAggregateRoot{}public interface IRepository<TEntity, in TId> where TEntity : IAggregateRoot<TId>{void Modify(TEntity entity);void Add(TEntity entity);void Remove(TId id);IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> predicate);IQueryable<TEntity> All();TEntity Find(TId id);}
}
namespace DDD.Infrastructure.Domain
{public class BusinessRule{private string _property;private string _rule;public BusinessRule(string rule){this._rule = rule;}public BusinessRule(string property, string rule){this._property = property;this._rule = rule;}public string Property{get { return _property; }set { _property = value; }}public string Rule{get { return _rule; }set { _rule = value; }}}}
namespace DDD.Infrastructure.Domain
{/// <summary>/// Abstract Base Class for Value Objects/// Based on CodeCamp Server codebase http://code.google.com/p/codecampserver/// </summary>/// <typeparam name="TObject">The type of the object.</typeparam>[Serializable]public class ValueObject<TObject> : IEquatable<TObject> where TObject : class{/// <summary>/// Implements the operator ==./// </summary>/// <param name="left">The left.</param>/// <param name="right">The right.</param>/// <returns>The result of the operator.</returns>public static bool operator ==(ValueObject<TObject> left, ValueObject<TObject> right){if (ReferenceEquals(left, null))return ReferenceEquals(right, null);return left.Equals(right);}/// <summary>/// Implements the operator !=./// </summary>/// <param name="left">The left.</param>/// <param name="right">The right.</param>/// <returns>The result of the operator.</returns>public static bool operator !=(ValueObject<TObject> left, ValueObject<TObject> right){return !(left == right);}/// <summary>/// Equalses the specified candidate./// </summary>/// <param name="candidate">The candidate.</param>/// <returns>/// true if the current object is equal to the <paramref name="candidate"/> parameter; otherwise, false./// </returns>public override bool Equals(object candidate){if (candidate == null)return false;var other = candidate as TObject;return Equals(other);}/// <summary>/// Indicates whether the current object is equal to another object of the same type./// </summary>/// <param name="other">An object to compare with this object.</param>/// <returns>/// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false./// </returns>public virtual bool Equals(TObject other){if (other == null)return false;Type t = GetType();FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);foreach (FieldInfo field in fields){object otherValue = field.GetValue(other);object thisValue = field.GetValue(this);//if the value is null...if (otherValue == null){if (thisValue != null)return false;}//if the value is a datetime-related type...else if ((typeof(DateTime).IsAssignableFrom(field.FieldType)) ||((typeof(DateTime?).IsAssignableFrom(field.FieldType)))){string dateString1 = ((DateTime)otherValue).ToLongDateString();string dateString2 = ((DateTime)thisValue).ToLongDateString();if (!dateString1.Equals(dateString2)){return false;}continue;}//if the value is any collection...else if (typeof(IEnumerable).IsAssignableFrom(field.FieldType)){IEnumerable otherEnumerable = (IEnumerable)otherValue;IEnumerable thisEnumerable = (IEnumerable)thisValue;if (!otherEnumerable.Cast<object>().SequenceEqual(thisEnumerable.Cast<object>()))return false;}//if we get this far, just compare the two values...else if (!otherValue.Equals(thisValue))return false;}return true;}/// <summary>/// Serves as a hash function for a particular type./// </summary>/// <returns>/// A hash code for the current <see cref="T:System.Object"/>./// </returns>public override int GetHashCode(){IEnumerable<FieldInfo> fields = GetFields();const int startValue = 17;const int multiplier = 59;int hashCode = startValue;foreach (FieldInfo field in fields){object value = field.GetValue(this);if (value != null)hashCode = hashCode * multiplier + value.GetHashCode();}return hashCode;}/// <summary>/// Gets the fields./// </summary>/// <returns>FieldInfo collection</returns>private IEnumerable<FieldInfo> GetFields(){Type t = GetType();var fields = new List<FieldInfo>();while (t != typeof(object)){fields.AddRange(t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));t = t.BaseType;}return fields;}}
}
转载于:https://www.cnblogs.com/liubiaocai/p/3938230.html
DDD领域驱动设计之领域基础设施层相关推荐
- ddd领域驱动设计_领域驱动设计(DDD)理论启示
过去几年通天塔一直处于快速的业务能力建设和架构完善的阶段,以应对不断增长的业务需求和容量.高可用等技术需求,现在通天塔平台已经能满足集团主站的大部分活动.频道搭建和运营能力,主流程的新需求越来越少,个 ...
- 基于ABP落地领域驱动设计-04.领域服务和应用服务的最佳实践和原则
围绕DDD和ABP Framework两个核心技术,后面还会陆续发布核心构件实现.综合案例实现系列文章,敬请关注! ABP Framework 研习社(QQ群:726299208) ABP Frame ...
- 实现DDD领域驱动设计: Part 1
原文链接: https://dev.to/salah856/implementing-domain-driven-design-part-i-5a72 简单的代码! 踢足球很简单,难的是踢简单的足球. ...
- ABP学习实践(十六)--领域驱动设计(DDD)回顾
ABP框架并没有实现领域驱动设计(DDD)的所有思想,但是并不妨碍用领域驱动的思想去理解ABP库框架. 1.领域驱动设计(DDD)与微服务(MicroService)的关系? 领域驱动设计(DDD)是 ...
- DDD - 一文读懂DDD领域驱动设计
一文读懂DDD领域驱动设计 1. 领域驱动设计简介 1.1 什么是领域驱动设计 1.2 为什么要用领域驱动设计 优点 缺点 2.3 领域驱动设计过程 2. 对于DDD,我们需要学习什么? 2.1 DD ...
- 如何系统学习领域驱动设计(DDD)?
作者简介 张逸,曾先后就职于中兴通讯.惠普 GDCC.中软国际.ThoughtWorks 等大型中外企业,任职角色为高级软件工程师.架构师.技术总监.首席咨询师. 精通包括 Java.Scala.Py ...
- 【吐血推荐】领域驱动设计学习输出
一.Hello DDD 刚开始接触学习「DDD - 领域驱动」的时候,我被各种新颖的概念所吸引:「领域」.「领域驱动」.「子域」.「聚合」.「聚合根」.「值对象」.「通用语言」.....总之一大堆有关 ...
- 基于ABP落地领域驱动设计-06.正确区分领域逻辑和应用逻辑
系列文章 基于ABP落地领域驱动设计-01.全景图 基于ABP落地领域驱动设计-02.聚合和聚合根的最佳实践和原则 基于ABP落地领域驱动设计-03.仓储和规约最佳实践和原则 基于ABP落地领域驱动设 ...
- 如何使用ABP框架(2)三层架构与领域驱动设计的对比
本文来自长沙.NET技术社区,原创:邹溪源.全文共有8500字,读完需耗时10分钟. 题图来自@pixabay 简述 上一篇简述了ABP框架中的一些基础理论,包括ABP前后端项目的分层结构,以及后端项 ...
最新文章
- unity3d游戏开发猜想——当程序猿老去
- 机会与挑战:2019人工智能应用趋势预测
- 对称加密算法DES,3重DES,TDEA,Blowfish,RC5,IDEA,AES。
- 线性霍尔传感器SS495、A1308、A1302
- 既要宽广,又要深邃,这也行
- 【算法精讲】集成分类与随机森林
- 27.CSS3文本效果
- Oracle一定有sqlplus吗,oracle sqlplus执行sql文件
- 高等数学下-赵立军-北京大学出版社-题解-练习8.4
- [css] 你了解css3的currentColor吗?举例说明它的作用是什么?
- tcp窗口滑动以及拥塞控制
- 集合python_python集合访问的方法
- mysql binlog备份_MySQL mysqldump + mysqlbinlog 备份和还原
- 单点登录SSO的实现原理与方案详解
- php mess,Mess.php
- 微信小程序 背景图片设置
- 附全文 |《数字中国指数报告2019》重磅发布,下一个数字经济增长点将由产业驱动...
- 二维码扫描登录,你必须知道的 3 件事!
- 此ca根目录证书不受信任
- adb控制移动数据、wifi开关、下拉菜单栏