这样设计是否更好些~仓储接口是否应该设计成基础操作接口和扩展操作接口

前言

我们进行linq to sql和ef时代后,底层的实现基本使用的是repository模块,即仓储模式,事实上就是把ORM实体的最基本操作进行封闭,对外层不公开操作实现的细节。

面向接口的编程

一个规定,多个实现,这可能是接口给我们带来的最直观的印象了,比如一个仓储在定义后,你可以用linq to sql实现它,也可以用ef去实现它,再或者使用ado.net去实现它,但它对外暴露的永远是稳定的接口,这里我们称为IRepository。

仓储接口是否应该设计成基础操作接口和扩展操作接口

这是今天说的重点,我们把仓储的最基本操作提炼出来,放到IRepository接口里,它叫做基本操作接口;将集合操作及其它附加操作放在IExtensionRepository接口里,我们称它为扩展操作接口;而我们再建立一个完成功能的接口ICompleteRepository,它会集成前两个接口,当调用方要求使用IRepository和IExtensionRepository的功能时,我们必须使用ICompleteRepository去声明对象,而简单的操作我们只需要使用IRepository去声明对象即可。

 IRepository接口我们可以这样定义:

  public interface IRepository<TEntity>

           where TEntity : class

    {

        /// <summary>

        /// 添加实体并提交到数据服务器

        /// </summary>

        /// <param name="item">Item to add to repository</param>

        void Insert(TEntity item);



        /// <summary>

        /// 移除实体并提交到数据服务器

        /// 如果表存在约束,需要先删除子表信息

        /// </summary>

        /// <param name="item">Item to delete</param>

        void Delete(TEntity item);



        /// <summary>

        /// 修改实体并提交到数据服务器

        /// </summary>

        /// <param name="item"></param>

        void Update(TEntity item);



        /// <summary>

        /// Get all elements of type {T} in repository

        /// </summary>

        /// <returns>List of selected elements</returns>

        IQueryable<TEntity> GetModel();



        /// <summary>

        /// 根据主键得到实体

        /// </summary>

        /// <param name="id"></param>

        /// <returns></returns>

        TEntity Find(params object[] id);

    }

对于扩展的功能接口,我们可以这样去定义:

/// <summary>

    /// 扩展的Repository操作规范

    /// </summary>

    public interface IExtensionRepository<TEntity> where TEntity : class

    {

        /// <summary>

        /// 添加集合

        /// </summary>

        /// <param name="item"></param>

        void Insert(IEnumerable<TEntity> item);



        /// <summary>

        /// 修改集合

        /// </summary>

        /// <param name="item"></param>

        void Update(IEnumerable<TEntity> item);



        /// <summary>

        /// 删除集合

        /// </summary>

        /// <param name="item"></param>

        void Delete(IEnumerable<TEntity> item);



        /// <summary>

        /// 扩展更新方法,只对EF支持

        /// </summary>

        /// <param name="entity"></param>

        void Update(System.Linq.Expressions.Expression<Action<TEntity>> entity);



        /// <summary>

        /// 根据指定规约得到延时结果集

        /// </summary>

        /// <param name="specification"></param>

        /// <returns></returns>

        IQueryable<TEntity> GetModel(Commons.Entity.Specification.ISpecification<TEntity> specification);



        /// <summary>

        ///  根据指定lambda得到延时结果集

        /// </summary>

        /// <param name="predicate"></param>

        /// <returns></returns>

        IQueryable<TEntity> GetModel(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate);



        /// <summary>

        ///  根据指定规约得到实体

        /// </summary>

        /// <param name="specification"></param>

        /// <returns></returns>

        TEntity Find(Commons.Entity.Specification.ISpecification<TEntity> specification);



        /// <summary>

        /// 根据指定lambda得到实体

        /// </summary>

        /// <param name="predicate"></param>

        /// <returns></returns>

        TEntity Find(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate);



    }

而为了使业务层即有IRepository而且还有IExtensionRepository接口的功能,我们将建立一个完整操作的接口,它由仓储实现基类去集成,在业务层,可以声明

这个完整的仓储接口:

    /// <summary>

    /// 完整的数据操作接口

    /// 完整的接口中,包括两个事件

    /// </summary>

    public interface ICompleteRepository<T> :

        IRepository<T>,

        IExtensionRepository<T>

         where T : class

    {

        /// <summary>

        /// Occurs after data saved

        /// </summary>

        event EventHandler<SavedEventArgs> AfterSaved;



        /// <summary>

        /// Occurs before data saved

        /// </summary>

        event EventHandler<SavedEventArgs> BeforeSaved;



    }

一个仓储基类将去实现它,当然你的仓储基类根据ORM不同,可以会有多个版本,你可以配合IOC来动态干这件事,呵呵!

如图:

再看一下传统DAL层图:(比较喜欢DDD架构,对于简单业务还是可以使用这种传统架构的)

好了,今天的仓储接口就讨论到这里吧,呵呵,对于一个问题的答案,在不同的场合,环境下很可能是不同的,而我们的架构也应该根据不同的业务需求,灵活去应对,这样,才会设计出更合理的架构!

年青人,你要敢于去创新!

你可能感兴趣的:(接口)