上一篇文章我们讲了经典DDD架构对比传统三层架构的优势,以及经典DDD架构每一层的职责后,本篇文章将介绍基础结构层中支持DDD的轻量级框架的主要代码。
这里需要说明的是,DDD轻量级框架能够体现DDD的思想即可,没必要做得很重,你也可以根据理解,自己实现支持DDD的框架。
1.实体、聚合根与值对象的顶层体现
实体顶层定义:
public interface IEntity
{
string Code { get; set; }
Guid Id { get; set; }
}
Id是一个未来存储到数据库表中的技术主键,Code是领域对象的唯一业务标识符。你也可以扩展这个接口,定义两个实体比较接口(未来实现就是比较两个实体如果Code一致,则代表两个实体相等)。
聚合根顶层定义:
public interface IAggregationRoot:IEntity
{
}
聚合根接口就是从实体接口继承,只是未来的用法可以在仓储中定义持久化时的领域对象必须从这个接口或继承了这个接口的抽象类继承下来的。
值对象顶层定义:
public interface IValueObject
{
Guid Id { get; set; }
}
值对象接口只需要保留一个技术主键即可,它没有业务标识符。在数据库中,值对象可能作为单独表存储,也可以作为实体的一部分存储。你也可以扩展这个接口,定义两个值对象比较接口(未来实现
就是比较两个值对象如果所有属性值一致,则代表两个值对象相等)。
工作单元顶层定义:
public interface IUnitOfWork
{
void Commit();
}
工作单元接口就定义了一个提交方法,在具体实现时,其实就是对应的EF Core的整个聚合的事务提交方法。
仓储接口顶层定义:
public interface IRepository:IUnitOfWork,IDisposable
{
}
仓储接口从工作单元接口与资源释放接口继承,为未来的数据访问框架和可替换性提供顶层约束。
EF Core顶层仓储持久化实现:
public class EFCoreRepository : IRepository
{
private readonly DbContext context;
public EFCoreRepository(DbContext context)
{
this.context = context;
}
public void Commit()
{
try
{
context.SaveChanges();
}
catch(Exception error)
{
throw error;
}
}
public void Dispose()
{
context.Dispose();
}
}
从上述代码中可以看到,主要实现了仓储接口的Commit方法,其实就是使用了EF Core的DbContext数据访问上下文类的SaveChanges()事务提交方法,应用服务层的用例就可以获取到某个聚合根的当前状态,然后调用仓储接口的Commit方法,实现了整个聚合所有对象的一次性事务提交。
2.常用工具类的实现
我们还应该定义另一个项目,这个项目是整个系统都需要使用到的工具,其中至少应该包括Asp.net Core Json配置文件的读,Json序列化与反序列化,加密,依赖注入,返回给前端的对象格式定义等,这里
先列出几个需要的,其他的在后面具体案例中在补充。
Asp.net Core Json配置文件读取:
Json配置文件会存储我们的一些配置信息,比如数据库连接字符串,微信AppId与AppSecure等,所以需要有功能支持Json配置文件的Key到Value的读取
public class AppSetting
{
private static IConfigurationSection appsections = null;
public static void SetAppSetting(IConfigurationSection section)
{
appsections = section;
}
public static string GetAppSetting(string key)
{
string str = "";
if (appsections.GetSection(key) != null)
{
str = appsections.GetSection(key).Value;
}
return str;
}
}
返回前端的对象格式定义:
我们的应用服务层将返回WebApi接口一定的数据格式,WebApi接口也会将这个数据返回给前端,前端拿到后就会做相应的处理。
public class ResultEntity<T>
{
public bool IsSuccess { get; set; }
public string Msg { get; set; }
public T Data { get; set; }
public int ErrorCode { get; set; }
public int Count { get; set; }
}
public class BaseAppSrv
{
protected ResultEntity<T> GetResultEntity<T>(T vobj,string msg="未成功获取到对象",int errorcode = 0)
{
var ueresult = new ResultEntity<T>();
var issuccess = true;
if(vobj is int && Convert.ToInt32(vobj) <= 0)
{
issuccess = false;
}
else if(vobj is bool && !Convert.ToBoolean(vobj))
{
issuccess = false;
}
else if(vobj is string && string.IsNullOrEmpty(Convert.ToString(vobj)))
{
issuccess = false;
}
if (!issuccess)
{
ueresult.Msg = msg;
ueresult.ErrorCode = 200;
}
ueresult.IsSuccess = issuccess;
ueresult.Data = vobj;
return ueresult;
}
}
未来所有的用例都将从BaseAppSrv继承,最终返回的格式都是ResultEntity<T>。
好了,基本的框架搭建好了,下一章就可以直接进入案例,看案例中如何通过DDD思想进行设计,并通过经典DDD架构与DDD轻量级框架进行实际业务系统的代码编写。