領域驅動設計實戰案例(七):訂單上下文應用服務用例與接口

DDD實戰進階第一波:開發通常業務的大健康行業直銷系統web

上一篇文章咱們主要講了訂單上下文的領域邏輯,在領域邏輯中完成了訂單項的計算邏輯、訂單的計算邏輯以及如何生成相應的實體code,這篇文章咱們經過在應用服務中實現一個下單的用例,來將這些領域邏輯以及倉儲整合起來,完成一個下單的用例。api

先看下單用例主體的代碼:微信

public class CreateOrderUseCase:BaseAppSrv框架

{
    private readonly IOrderRepository iorderrepository;
    private readonly IDealerRepository idealerrepository;
    private readonly IRepository[] irepositories;
    

    public CreateOrderUseCase(IOrderRepository iorderrepository,IDealerRepository idealerrepository,
        params IRepository[] irepositories)
    {
        this.iorderrepository = iorderrepository;
        this.idealerrepository = idealerrepository;
        this.irepositories = irepositories;
    }
    public ResultEntity<bool> CreateOrder(OrderDTO orderdto)
    {
        var orderid = Guid.NewGuid();
        Orders order = new Orders();
        var productskus = new List<ProductSKU>();
        for(int i = 0; i < orderdto.ProductSPUNames.Count; i++)
        {
            var productsku = new ProductSKU();
            productsku.ProductSPUName = orderdto.ProductSPUNames[i];
            productsku.DealerPrice = orderdto.ProductDealerPrices[i];
            productsku.PV = orderdto.ProductPVS[i];
            productsku.Id = orderdto.ProductSKUIds[i];
            productsku.Spec = orderdto.ProductSepcs[i];
            productskus.Add(productsku);
        }
        var contact = new Contact();
        contact.ContactName = orderdto.ContactName;
        contact.ContactTel = orderdto.ContactTel;
        contact.Province = orderdto.Privence;
        contact.City = orderdto.City;
        contact.Zero = orderdto.Zero;
        contact.Street = orderdto.Street;

        var orders = order.CreateOrders(orderid, orderdto.DealerId, productskus, orderdto.Counts,
            contact);

        try
        {
            //using (var tansaction = new TransactionScope())
            //{
                using (irepositories[1])
                {
                    idealerrepository.SubParentEleMoney(orderdto.DealerId, order.OrderTotalPrice.TotalPrice);
                    idealerrepository.AddDealerPV(orderdto.DealerId, order.OrderTotalPV.TotalPV);
                    irepositories[1].Commit();

                }

                using (irepositories[0])
                {
                    iorderrepository.CreateOrder(orders);
                    irepositories[0].Commit();
                }
            return GetResultEntity(true);
                //tansaction.Complete();
            //}
        }
        catch(EleMoneyNotEnoughException error)
        {
            throw error;
        }
        catch(Exception error)
        {
            throw error;
        }
        
    }
}

IOrderRepository倉儲接口主要完成訂單的預持久化工做,咱們來看下它的實現:ssh

public class OrderEFCoreRepository : IOrderRepositoryide

{
    private readonly DbContext context;
        
    public OrderEFCoreRepository(DbContext context)
    {
        this.context = context;
    }
    public void CreateOrder<T>(T order) where T:class,IAggregationRoot
    {
        var ordercontext = this.context as OrderEFCoreContext;
        var ordernew = order as Orders;
        try
        {
            ordercontext.Order.Add(ordernew);
        }
        catch(Exception error)
        {
            throw error;
        }
    }

} ui

IDealerRepository倉儲接口主要用來下單完成後,扣減對應經銷商的電子幣與累加PV,相關方法實現代碼以下:this

public void SubParentEleMoney(Guid parentdealerid, decimal subelemoney)idea

{
        var dealercontext = this.context as DealerEFCoreContext;
        var parentdealer = dealercontext.Dealer.Single(p => p.Id == parentdealerid);
        parentdealer.TotalEleMoney = parentdealer.TotalEleMoney - subelemoney;
        if (parentdealer.TotalEleMoney < 0)
        {
            throw new EleMoneyNotEnoughException("電子幣不夠進行此操做!");
        }
        try
        {
            dealercontext.Entry(parentdealer).State = EntityState.Modified;
        }
        catch(Exception error)
        {
            throw error;
        }
    }

    public void AddDealerPV(Guid dealerid, decimal orderpv)
    {
        var dealercontext = this.context as DealerEFCoreContext;
        var dealer = dealercontext.Dealer.Single(p => p.Id == dealerid);
        dealer.TotalPV = dealer.TotalPV +orderpv;
        try
        {
            dealercontext.Entry(dealer).State = EntityState.Modified;
        }
        catch (Exception error)
        {
            throw error;
        }
    }

IRepository[]用於訂單與經銷商兩個的數據訪問倉儲,完成真正的持久化,在第一部分主體代碼中註釋掉的using (var tansaction = new TransactionScope())與
tansaction.Complete();是由於在.net core 2.0版本中,不支持多個數據訪問上下文的事務,在.net core 2.1版本中能夠使用,這樣就完成了訂單數據與經銷商數據的事務一致性。.net

最後咱們經過webapi完成對應用服務的調用,實現代碼以下

[HttpPost]

[Route("CreateOrder")]
    public ResultEntity<bool> CreateOrder([FromBody] OrderDTO orderdto)
    {
        var result = new ResultEntity<bool>();
        var ordercontext = new OrderEFCoreContext();
        var dealercontext = new DealerEFCoreContext();
        var irepository = new EFCoreRepository(ordercontext);
        var irepository1 = new EFCoreRepository(dealercontext);
        var iorderrepository = new OrderEFCoreRepository(ordercontext);
        var idealerrepository = new DealerEFCoreRepository(dealercontext);
        var createorderusecase = new CreateOrderUseCase(iorderrepository, idealerrepository,
            irepository, irepository1);
        try
        {
            result = createorderusecase.CreateOrder(orderdto);
            result.Count = 1;
            result.IsSuccess = true;
            result.Msg = "下單成功!";
        }
        catch (EleMoneyNotEnoughException error)
        {
            result.ErrorCode = 300;
            result.Msg = error.Message;
        }
        catch (Exception error)
        {
            result.ErrorCode = 200;
            result.Msg = error.Message;
        }
        return result;
    }

由於這裏只是作演示,具體接口與實現沒有經過依賴注入框架注入,這部份內容能夠本身去實現。

QQ討論羣:309287205 DDD實戰進階視頻請關注微信公衆號:msshcj

相關文章
相關標籤/搜索