zoukankan      html  css  js  c++  java
  • net core天马行空系列:降低net core门槛,数据库操作和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

  • 相关阅读:
    poj 1789 每个字符串不同的字母数代表两个结点间的权值 (MST)
    poj 1251 poj 1258 hdu 1863 poj 1287 poj 2421 hdu 1233 最小生成树模板题
    poj 1631 最多能有多少条不交叉的线 最大非降子序列 (LIS)
    hdu 5256 最少修改多少个数 能使原数列严格递增 (LIS)
    hdu 1025 上面n个点与下面n个点对应连线 求最多能连有多少条不相交的线 (LIS)
    Gym 100512F Funny Game (博弈+数论)
    UVa 12714 Two Points Revisited (水题,计算几何)
    UVa 12717 Fiasco (BFS模拟)
    UVa 12718 Dromicpalin Substrings (暴力)
    UVa 12716 && UVaLive 6657 GCD XOR (数论)
  • 原文地址:https://www.cnblogs.com/hezp/p/12747340.html
Copyright © 2011-2022 走看看