1、DDD领域驱动设计实践篇之如何提取模型

2、DDD领域驱动设计之聚合、实体、值对象

其实这里说的基础设施层只是领域层的一些接口和基类而已,没有其他的如日子工具等代码,仅仅是为了说明领域层的一些基础问题

1、领域事件简单实现代码,都是来至ASP.NET设计模式书中的代码

namespace DDD.Infrastructure.Domain.Events
{
public interface IDomainEvent
{
}
}
namespace DDD.Infrastructure.Domain.Events
{
public interface IDomainEventHandler<T> : IDomainEventHandler
where 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;
} }
}

  

DDD领域驱动设计之领域基础设施层的更多相关文章

  1. DDD领域驱动设计之领域服务

    1.DDD领域驱动设计实践篇之如何提取模型 2.DDD领域驱动设计之聚合.实体.值对象 3.DDD领域驱动设计之领域基础设施层 什么是领域服务,DDD书中是说,有些类或者方法,放实体A也不好,放实体B ...

  2. 基于ABP落地领域驱动设计-04.领域服务和应用服务的最佳实践和原则

    目录 系列文章 领域服务 应用服务 学习帮助 系列文章 基于ABP落地领域驱动设计-00.目录和前言 基于ABP落地领域驱动设计-01.全景图 基于ABP落地领域驱动设计-02.聚合和聚合根的最佳实践 ...

  3. DDD领域驱动设计:领域事件

    1 前置阅读 在阅读本文章之前,你可以先阅读: DDD领域驱动设计是什么 DDD领域驱动设计:实体.值对象.聚合根 DDD领域驱动设计:仓储 MediatR一个优秀的.NET中介者框架 2 什么是领域 ...

  4. DDD领域驱动设计之运用层代码

    1.DDD领域驱动设计实践篇之如何提取模型 2.DDD领域驱动设计之聚合.实体.值对象 3.DDD领域驱动设计之领域基础设施层 4.DDD领域驱动设计之领域服务 5.整体DEMO代码 什么是运用层,说 ...

  5. 解构领域驱动设计(一):为什么DDD能够解决软件复杂性

    1 为什么我要研究领域驱动设计 1.1 设计方法各样且代码无法反映设计 我大概从2017年10月份开始研究DDD,当时在一家物流信息化的公司任职架构师,研究DDD的初衷在于为团队寻找一种软件设计的方法 ...

  6. 如何使用ABP进行软件开发(2) 领域驱动设计和三层架构的对比

    简述 上一篇简述了ABP框架中的一些基础理论,包括ABP前后端项目的分层结构,以及后端项目中涉及到的知识点,例如DTO,应用服务层,整洁架构,领域对象(如实体,聚合,值对象)等. 笔者也曾经提到,AB ...

  7. 基于ABP落地领域驱动设计-01.全景图

    什么是领域驱动设计? 领域驱动设计(简称:DDD)是一种针对复杂需求的软件开发方法.将软件实现与不断发展的模型联系起来,专注于核心领域逻辑,而不是基础设施细节.DDD适用于复杂领域和大规模应用,而不是 ...

  8. 基于ABP落地领域驱动设计-05.实体创建和更新最佳实践

    目录 系列文章 数据传输对象 输入DTO最佳实践 不要在输入DTO中定义不使用的属性 不要重用输入DTO 输入DTO中验证逻辑 输出DTO最佳实践 对象映射 学习帮助 系列文章 基于ABP落地领域驱动 ...

  9. 基于ABP落地领域驱动设计-06.正确区分领域逻辑和应用逻辑

    目录 系列文章 领域逻辑和应用逻辑 多应用层 示例:正确区分应用逻辑和领域逻辑 学习帮助 系列文章 基于ABP落地领域驱动设计-00.目录和前言 基于ABP落地领域驱动设计-01.全景图 基于ABP落 ...

随机推荐

  1. Python学习(基础简绍)

    今天终于开始了python的学习,至于python的历史我就不说了,百度百科中太详细了,我这里说就是关公面前耍大刀,太自不量力了,所以,废话不多说,直接讲讲我惊天学习Python的收获吧. 1.Pyt ...

  2. GDI+ 发生一般性错误解决办法

    错误的代码g对象继续占用 未释放资源 如果路径不一样 没问题 相同路径 获取图片进行 缩略会造成GDI错误 /// <summary> /// 生成缩略图 /// </summary ...

  3. 不支持C++11 decltype的噩耗

    前言:因为公司现在使用vs2008,所以很多c++11的新特性还未能使用,导致写了很多冤枉代码. 最初引擎的数学库非常简单,使用起来也不方便,例如: float FastLerp(const floa ...

  4. linux系统编程之I/O内核数据结构

    文件在内核中是用三种数据结构进行表示的 (1)文件描述符表:文件描述符表是一个结构体数组,数组的下标就是open函数返回的文件描述符. 文件描述符表的每一个记录有两个字段   *文件描述符标志 * 文 ...

  5. Spring和mybatis整合后的mybais-config.xml配置

    <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration PUBLIC & ...

  6. 关于swfupload,客户端中文乱码解决方案!

    公司做了个邮箱系统,上传附件用到了swfupload控件,测试成功上线后hr找我说上传附件中文乱码. 奇怪了,就只有她的电脑出问题,我找了好几台电脑,虚拟机也跑了怎么就找不到问题. 后来网上查了好久, ...

  7. IIS出现问题时修改配置文件的几项说明

    近期系统在线运行经常出现object moved错误 通过查询资料,做了几项web.config文件的调整 1,调整应用程序池使用集成模式      <system.webServer>  ...

  8. matlab linux 安装

    1. 获取matlab的iso文件,并挂载到目录下2. sudo sh $(matlab_path)/matlab安装(破解,相关见说明)3. 加入系统路径,将$(matlab_install_pat ...

  9. WEB响应布局

    [15/06月,15] em是相对长度单位.相对于当前对象内文本的字体尺寸.如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸.(引自CSS2.0手册) 任意浏览器的默认字体高都是1 ...

  10. flash 定义二维数组

    一种二维数组的定义方法   //假设二维数组为 [5][7]var  xn:Number = 5;var  yn:Number = 7; //定义一数值变量var  temp:Number = 0; ...