net core天马行空系列:降低net core门槛,数据库操作和http访问仅需写接口,实现类由框架动态生成
程序员文章站
2022-07-01 15:50:20
引文 hi,大家好,我是三合。不知各位有没有想过,如果能把数据库操作和http访问都统一封装成接口(interface)的形式, 然后接口对应的实现类由框架去自动生成,那么必然能大大降低工作量,因为不需要去写很多重复的代码了,还有一个好处是,都是提供接口,我们把原来数据库操作的部分,改成http访问 ......
引文
hi,大家好,我是三合。不知各位有没有想过,如果能把数据库操作和http访问都统一封装成接口(interface)的形式,
然后接口对应的实现类由框架去自动生成,那么必然能大大降低工作量,因为不需要去写很多重复的代码了,还有一个好处是,都是提供接口,我们把原来数据库操作的部分,改成http访问,对于业务层来说,是无感的,因为接口和方法都没变。致力于降低上手net core的门槛,我开源了summerboot项目,下面让我们来看一下效果。
数据库表对应实体类,这些都是常规操作,略过
重头戏,如何写接口,以一个简单的购物功能为例子
数据库访问
订单详情仓储
订单仓储
http访问
控制器中进行构造函数注入
实际调用
/// <summary> /// 添加订单 /// </summary> /// <param name="dto"></param> /// <returns></returns> [httppost("addorder")] public async task<iactionresult> addorder([frombody]addorderdto dto) { if (dto?.productlist==null) return badrequest("参数不能为空"); uow.begintransaction(); try { var orderheader = new orderheader { createtime = datetime.utcnow, customerno = dto.customerno, state = 1, orderno = guid.newguid().tostring("n") }; await orderheaderrepository.insertasync(orderheader); var orderdetaillist = new list<orderdetail>(); //总消费金额 var totalamount = 0m; dto.productlist.foreach(it => { var orderdetail = new orderdetail { orderheaderid = orderheader.id, productno = it.productno, productname = it.productname, quantity = it.quantity, price = it.price }; orderdetaillist.add(orderdetail); totalamount += it.quantity * it.price; }); await orderdetailrepository.batchinsertasync(orderdetaillist); //更新用户消费金额 var success = await customerrepository.updatecustomeramount(dto.customerno, totalamount); if (!success) { uow.rollback(); return badrequest(); } } catch (exception e) { uow.rollback(); } uow.commit(); return ok(); } /// <summary> /// 删库跑路 /// </summary> /// <returns></returns> [httpget("deletedatabase")] public async task deletedatabase() { await orderheaderrepository.deleteallorder(); } /// <summary> /// 根据会员编号取消订单 /// </summary> /// <param name="customerno"></param> /// <returns></returns> [httpget("cancelorderbycustomerno")] public async task<bool> cancelorderbycustomerno(string customerno) { var count = await orderheaderrepository.cancelorderbycustomernoasync(customerno); return count > 0; } /// <summary> /// 分页,根据会员编号获取消费详情 /// </summary> /// <param name="customerno"></param> /// <returns></returns> [httpget("queryorderdetailbycustomernobypage")] public async task<page<orderdetail>> queryorderdetailbycustomernobypage(int pagenumber,int pagesize, string customerno) { var page=new pageable(pagenumber,pagesize); var result = await orderdetailrepository.getorderdetailbycustomernobypageasync(page,customerno); return result; } /// <summary> /// 根据会员编号获取消费详情 /// </summary> /// <param name="customerno"></param> /// <returns></returns> [httpget("queryorderdetailbycustomerno")] public async task<list<orderdetail>> queryorderdetailbycustomerno(string customerno) { var result= await orderdetailrepository.getorderdetailbycustomernoasync(customerno); return result; }
动态生成接口实现类的原理
最开始写的时候,思路是,采用aop思想,castle动态生成接口实现类,实现类里的方法都没有具体实现,然后在切面里对方法进行拦截并且模拟方法的实现,提供返回值,java中很多骚操作就是这么实现的,但是后来发现在.net
中这种实现方式有很大的弊端,因为.net有异步方法,而castle对于异步方法的支持是很弱的,不足以实现最开始的设想,于是,我换了一种思路,在数据库操作和http调用中,抛开动态实现类这个壳子,具体执行操作的类是恒定不变的,
那么利用emit技术动态路由到要执行的方法就行了。
写在最后
如果这篇文章对你有所启发不妨点个赞吧。
github地址:https://github.com/tripleview/summerboot,欢迎star!
qq群:799648362
nuget包:summerboot
上一篇: 爸爸妈妈,带孩子,没有你们这样的。
下一篇: 16_多线程