统一的仓储接口

目前,各种数据访问组件多如牦牛,提供接口各不相同,虽然大多都支持不同数据存储,但是还是存在一些问题,

 有的团队成员喜欢用EF,有的喜欢用NHibernate,口味难调。于是我希望能有一组标准的接口,这样可以统一

代码的,也可以满足各成员的喜好。

目前来说,linq的出现,大大简化了代码的冗余和复杂性,

所以这组接口是建立在linq的基础上的,支持linq的数据访问组件目前有EF,NHibernate,IQtoolkit,Dblinq等。

 这里面有两个重要的对象,Context(上下文对象)和Repository(仓储对象)。

我希望调用者只需要尽量少的对象和尽量少的方法。使得接口清晰简单。

首先上下文对象Context,它能够获得仓储对象并完成事务提交即可。

public  interface IObjectContext:IDisposable
{
     string Name {  getset; }
    IRepository GetRepository<T>();

bool SaveChanges();

}

 接着仓储对象Repository,它则可以对T类型的数据进行CRUD,并且还能像IQueryable那样支持很多操作。

 public interface IRepository<T> : IQueryable<T> where T : class,IEntity, new()

    {
        T CreateModel();
         bool New(T entity);
         bool Update(T entity);
         bool Delete(T t);
         bool VirtualDelete(T t);
        Guid NewGuid();
         decimal NewId();
    }

仓储对不同数据访问组件有些共同的东西,加之实现IQueryable,所以增加抽象类AbstractRepository

public  abstract  class AbstractRepository<T> : IRepository<T>  where T :  class,IEntity,  new()
    {
         public IObjectContext Context {  getprivate  set; }
         public AbstractRepository(IObjectContext context)
        {
            Context = context;
        }
         protected  abstract IQueryable<T> GetQueryable();
         public  abstract  bool New(T entity);
         public  abstract  bool Update(T entity);
         public  abstract  bool Delete(T t);
         public  abstract  bool VirtualDelete(T t);
         public  virtual T CreateModel()
        {
             return  new T();
        }
         public  virtual Guid NewGuid() {  return Guid.NewGuid(); }
         public  virtual  decimal NewId() {  return  decimal.Zero; }

         public IEnumerator<T> GetEnumerator()
        {
             return GetQueryable().GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
             return GetQueryable().GetEnumerator();
        }

         public Type ElementType
        {
             get {  return GetQueryable().ElementType; }
        }

         public Expression Expression
        {
             get {  return GetQueryable().Expression; }
        }

         public IQueryProvider Provider
        {
             get {  return GetQueryable().Provider; }
        }

    } 

主要的就需要这三个接口

 代码写起来就是这样子

 using (var context = ContextFactory.Create(contextName))

            {
                 var r = context.GetRepository<T>();
                 var instance = r.CreateModel();
                instance.Copy(tdto);
                instance.Validate(context);
                r.New(instance);
                context.SaveChanges();
                 return instance;
            }

 这些重复性的代码,直接扩展到接口上,封装起来,外面只需继承此接口。

 下面是EF的仓储实现

 public class EFRepository<T> : AbstractRepository<T> where T : class,IEntity, new()

    {
        ObjectContext _context =  null;
         public EFRepository(IObjectContext context) :  base(context) {
            _context =  base.Context  as ObjectContext;
             if (_context ==  null) {  throw  new Exception( " EFRepository中上下文对象不是System.Data.Objects.ObjectContext对象。 "); }
        }
         public  override  bool New(T entity)
        {
            GetObjectSet().AddObject(entity);
             return  true;
        }

         public  override  bool Update(T entity)
        {
             return  true;
        }

         public  override  bool Delete(T t)
        {
            GetObjectSet().DeleteObject(t);
             return  true;
        }

         public  override  bool VirtualDelete(T t)
        {
             return  true;
        }

         protected  override IQueryable<T> GetQueryable()
        {
             return GetObjectSet();
        }

        ObjectSet<T> GetObjectSet()
        {
             return _context.CreateObjectSet<T>();
        }
    }

其它的仓储实现也比较简单,附上源码

 Repository.rar

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