asp.net core 实现一个简单的仓储的方法
一直有自己写个框架的想法,但是一直没有行动起来,最近比较闲,正好可以开工了.
现在已经完成了两部分.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的东西显然是不合适的,下一步要实现一个框架自身的模块加载方式.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: 详解javascript void(0)