Master.DADI(Data Access Domain Interface)框架——数据操作领域接口(一)

来源:互联网 发布:苹果mac使用教程 编辑:程序博客网 时间:2024/05/21 09:05

了解大地(DADI)


DADI 全称为 Data Access Domain Interface,即数据访问层领域接口。是针对 DDD(Domain Driven Development 领域驱动开发)中在数据访问层中定义的一套领域接口。由于数据访问是对存储介质(数据库或其他存储方式)最后一道工序,就好比世间的天、地、人一样,地是最底下的一层,其次是人,上面是天。因此取名为DADI(大地)。


如今,现在对于数据访问层多半使用的都是各个版本的ORM框架,但他们彼此各不相通,而“大地”可以使他们都能联通起来,在切换时易如反掌。


下面我就来介绍内部的一些内容。


IEntity 实体接口

namespace Master.DADI{    /// <summary>    /// 表示当前对象为一个实体。    /// </summary>    /// <typeparam name="TKey">主键类型。</typeparam>    public interface IEntity<TKey>    {        /// <summary>        /// 获取或设置作为实体的唯一标识。        /// </summary>        TKey Id { get; set; }    }}

PS:“大地”中的代码都是定义,没有任何实现。这是 DDD 的一个基本准则。

因此,IEntity接口提供了一个泛型类型,要求实现者自行定义与自己相关的项目的实体唯一标识的类型。


举个例子:项目A要求的主键是int 自增类型,你可以定义一个基类,继承该接口,然后设置TKey为int类型;项目B可能又要求是GUID的,那就可以自行设置成GUID的。

这样就能满足每一个项目不同的需求。


IDbContext 接口

    /// <summary>    /// 提供基本的数据上下文功能。    /// </summary>    public interface IDbContext    {        /// <summary>        /// 将所有内存中的仓储对象中未提交的修改保存至物理储存中。        /// </summary>        void Commit();        /// <summary>        /// 抛弃所有未提交的修改,并重置事务模式。        /// </summary>        void Rollback();    }

该接口与工作单元(IUnitOfWork)功能类似,主要是作为一个事务关系来处理。



IAggregateRoot 聚合根接口

    /// <summary>    /// 表示当前对象为领域设计的聚合根。    /// </summary>    public interface IAggregateRoot<TKey>:IEntity<TKey>    {    }

在DDD开发模式中,聚合根是一个很重要的元素,所以在仓储中的操作都针对的是聚合根。


ISpecification 规格接口

    using System;    using System.Linq.Expressions;    /// <summary>    /// 提供一个基本的规格功能。    /// </summary>    /// <typeparam name="TEntity">实体类型。</typeparam>    /// <typeparam name="TKey">主键类型。</typeparam>    public interface ISpecification<TEntity,TKey>        where TEntity : IEntity<TKey>    {        /// <summary>        /// 一个表示规格否满足的表达式。        /// </summary>        /// <returns>Linq 表达式。</returns>        Expression<Func<TEntity, bool>> SatisfiedBy();    }

需要传入2个类型,一个实体,一个是主键。你可以先定义一个适合你项目的规格基类,主要是确定好主键类型。


IRepository 仓储接口

 

 /// <summary>    /// 提供基本的仓储功能。    /// </summary>    /// <typeparam name="TEntity">实体仓储类型。</typeparam>    /// <typeparam name="TKey">主键类型。</typeparam>    public interface IRepository<TEntity,TKey> where TEntity : IAggregateRoot<TKey>    {        /// <summary>        /// 获取当前仓储功能的数据上下文对象。        /// </summary>        IDbContext DbContext { get; }        /// <summary>        /// 将指定对象新增到储存介质中。        /// </summary>        /// <param name="entity">一个实体对象。</param>        void Add(TEntity entity);        /// <summary>        /// 将指定对象更新到储存介质中。        /// </summary>        /// <param name="entity">一个实体对象。</param>        void Modify(TEntity entity);        /// <summary>        /// 将指定对象从储存介质中移除。。        /// </summary>        /// <param name="entity">一个实体对象。</param>        void Remove(TEntity entity);        /// <summary>        /// 获取指定主键 Id 的数据对象。        /// </summary>        /// <param name="id">Id 主键。</param>        /// <returns>若查找到数据,则返回该对象,否则为 null 。</returns>        TEntity Find(TKey id);        /// <summary>        /// 获取是否满足指定规格的数据集合。        /// </summary>        /// <param name="specification">一个规格功能对象。</param>        /// <returns>若查找到数据,则返回集合对象,否则为 null 或一个空的实例。</returns>        IEnumerable<TEntity> FindAll(ISpecification<TEntity,TKey> specification);        /// <summary>        /// 获取所有的数据集合。        /// </summary>        /// <returns>若查找到数据,则返回集合对象,否则为 null 或一个空的实例。</returns>        IEnumerable<TEntity> FindAll();        /// <summary>        /// 获取是否满足指定规格的数据分页集合。        /// </summary>        /// <param name="specification">一个规格功能对象。</param>        /// <param name="page">当前页码。</param>        /// <param name="itemPerPage">每一页的数据呈现数量。</param>        /// <returns>若查找到数据,则返回 <see cref="IPageEntity{TEntity}"/> 实例,否则为 null 或一个空的实例。</returns>        IPageEntity<TEntity> FindPaged(ISpecification<TEntity,TKey> specification, int page, int itemPerPage);    }

该接口把常用的一些操作进行了提炼,但这里都只是接口声明,并没有实现。因为实现是具体到ORM的具体方式,也许是EF,NHibernate,Petapoco等等。


总结

其实没啥好总结的,这只是定义,要结合下两篇来看会好很多,我已经写好了对EF和Petapoco对 “大地” 的两种实现,大家可以参考下。

0 0
原创粉丝点击