欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

asp.net core 实现一个简单的仓储的方法

程序员文章站 2022-03-07 12:20:54
一直有自己写个框架的想法,但是一直没有行动起来,最近比较闲,正好可以开工了. 现在已经完成了两部分.1.一个简单仓储,实现使用的是ef 2.ioc部分,这里是把内置的io...

一直有自己写个框架的想法,但是一直没有行动起来,最近比较闲,正好可以开工了.

现在已经完成了两部分.1.一个简单仓储,实现使用的是ef 2.ioc部分,这里是把内置的ioc替换成了aotofac,这部分感觉还是有一点缺陷的.下面说

仓储部分

这里主要是接口是实现,目前使用ef实现了仓储的接口.看一下代码

 public interface irepository<tentity, tprimarykey>
  where tentity : class
 {
  #region select/get/query

  iqueryable<tentity> getall();

  iqueryable<tentity> getallincluding(params expression<func<tentity, object>>[] propertyselectors);

  list<tentity> getalllist();

  task<list<tentity>> getalllistasync();

  list<tentity> getalllist(expression<func<tentity, bool>> predicate);

  task<list<tentity>> getalllistasync(expression<func<tentity, bool>> predicate);

  t query<t>(func<iqueryable<tentity>, t> querymethod);

  tentity get(tprimarykey id);

  task<tentity> getasync(tprimarykey id);

  tentity single(expression<func<tentity, bool>> predicate);

  task<tentity> singleasync(expression<func<tentity, bool>> predicate);

  tentity firstordefault(tprimarykey id);

  task<tentity> firstordefaultasync(tprimarykey id);

  tentity firstordefault(expression<func<tentity, bool>> predicate);

  task<tentity> firstordefaultasync(expression<func<tentity, bool>> predicate);

  tentity load(tprimarykey id);

  #endregion

  #region insert

  tentity insert(tentity entity);

  task<tentity> insertasync(tentity entity);

  #endregion

  #region update

  tentity update(tentity entity);

  task<tentity> updateasync(tentity entity);

  tentity update(tprimarykey id, action<tentity> updateaction);

  task<tentity> updateasync(tprimarykey id, func<tentity, task> updateaction);

  #endregion

  #region delete

  void delete(tentity entity);

  task deleteasync(tentity entity);

  void delete(tprimarykey id);

  task deleteasync(tprimarykey id);

  void delete(expression<func<tentity, bool>> predicate);

  task deleteasync(expression<func<tentity, bool>> predicate);

  #endregion

  #region aggregates

  int count();

  task<int> countasync();

  int count(expression<func<tentity, bool>> predicate);

  task<int> countasync(expression<func<tentity, bool>> predicate);

  long longcount();

  task<long> longcountasync();

  long longcount(expression<func<tentity, bool>> predicate);

  task<long> longcountasync(expression<func<tentity, bool>> predicate);

  #endregion
 }

下面是实现的部分代码,代码比较占版面,就不贴全了.

 public abstract class repositorybase<tentity, tprimarykey> : irepository<tentity, tprimarykey>
  where tentity : class
 {
  public abstract iqueryable<tentity> getall();

  public abstract iqueryable<tentity> getallincluding(params expression<func<tentity, object>>[] propertyselectors);

  public virtual list<tentity> getalllist()
  {
   return getall().tolist();
  }

  public virtual async task<list<tentity>> getalllistasync()
  {
   return await task.fromresult(getalllist());
  }
 }
 public class efrepositorybase<tdbcontext, tentity, tprimarykey> : repositorybase<tentity, tprimarykey>
  where tentity : class
  where tdbcontext : dbcontext
 {
  public virtual tdbcontext context { private set; get; }

  public virtual dbset<tentity> table => context.set<tentity>();

  public efrepositorybase(tdbcontext context)
  {
   context = context;
  }

  public override iqueryable<tentity> getall()
  {
   return table;
  }

  public override iqueryable<tentity> getallincluding(params expression<func<tentity, object>>[] propertyselectors)
  {
   if (propertyselectors == null)
   {
    return getall();
   }

   var linq = getall();

   foreach (var item in propertyselectors)
   {
    linq = linq.include(item);
   }

   return linq;
  }
 }

注意看efrepositorybase继承了repositorybase,而repositorybase实现了irepository.这里的repositorybase是所有实现的基类.getalllist虚方法直接调用了抽象方法getall,这样在efrepositorybase中就可以减少很多代码了.

这里有个坑 efrepositorybase 是不能直接注册到ioc中的,因为efrepositorybase和irepository的泛型参数个数不一致,ioc不能找到多出的一个泛型的值.使用仓储的时候继承efrepositorybase把dbcontext传进去就好了

public class testrepository<tentity, tprimarykey> : efrepositorybase<testcontext, tentity, tprimarykey> where tentity : class
{
 public testrepository(testcontext context)
  : base(context)
 {
 }
}

ioc部分

asp.net core 微软提供了一个简单的ioc,但是接口比较少,替换成我们熟悉的ioc框架就方便多了. asp.net core 也有很方便的替换ioc的方法.简单说就是修改configureservices方法的返回值为iserviceprovider.我使用了autofac,下面看代码.

public iserviceprovider configureservices(iservicecollection services)
{
 services.addmvc();

 return services.addluna<autofacmodule>();
}


public static iserviceprovider addluna<tmodule>([notnull]this iservicecollection services)
 where tmodule : imodule, new()
{
 var builder = new containerbuilder();
 builder.populate(services);
 builder.registermodule<tmodule>();

 return new autofacserviceprovider(builder.build());
}

public class autofacmodule : module
{
 protected override void load(containerbuilder builder)
 {
  builder.registertype<testcontext>();

  builder.registergeneric(typeof(testrepository<,>)).as(typeof(irepository<,>))
   .instanceperlifetimescope();
 }
}

这里的module和imodule是autofac的,功能已经实现了,但是作为框架来说直接暴露了autofac的东西显然是不合适的,下一步要实现一个框架自身的模块加载方式.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。