.NET核心问题中的清理/洋葱架构

时间:2020-04-29 15:29:17

标签: asp.net .net asp.net-core .net-core clean-architecture

关于清洁/洋葱架构,我有几个问题。我一直在阅读Microsoft文档,它指出应用程序核心在中间,而外层则在“依赖性”方面向内指向。 enter image description here

在这种情况下取​​决于它们到底是什么意思?当我想到依赖项时,我想到在类A内部实例化了类B,因此类A依赖于类B。但是,当我看一下eShopOnWeb存储库(https://github.com/dotnet-architecture/eShopOnWeb)时,它看起来就像架构核心具有将基础设施作为依赖项实施的回购协议,这不是矛盾的吗?

2 个答案:

答案 0 :(得分:0)

在这种情况下,A依赖于B意味着:A“了解” B。

外圈的类型可以使用内圈的类型,反之亦然。

请参阅:https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html

答案 1 :(得分:0)

...看来架构核心已将基础结构实现为依赖项,这是不是矛盾的?

您在这里缺少的是使用 接口 。让我们从应用程序核心层开始 OrderService

Grid

在应用程序核心中定义的 OrderService 仅具有 与接口的依赖关系 ,它们也定义在应用程序核心。

例如有

namespace Microsoft.eShopWeb.ApplicationCore.Services
{
    public class OrderService : IOrderService
    {
        private readonly IAsyncRepository<Order> _orderRepository;
        private readonly IUriComposer _uriComposer;
        private readonly IAsyncRepository<Basket> _basketRepository;
        private readonly IAsyncRepository<CatalogItem> _itemRepository;

        public OrderService(IAsyncRepository<Basket> basketRepository,
            IAsyncRepository<CatalogItem> itemRepository,
            IAsyncRepository<Order> orderRepository,
            IUriComposer uriComposer)
        {
            _orderRepository = orderRepository;
            _uriComposer = uriComposer;
            _basketRepository = basketRepository;
            _itemRepository = itemRepository;
        }

        public async Task CreateOrderAsync(int basketId, Address shippingAddress)
        {
            var basketSpec = new BasketWithItemsSpecification(basketId);
            var basket = await _basketRepository.FirstOrDefaultAsync(basketSpec);

            Guard.Against.NullBasket(basketId, basket);
            Guard.Against.EmptyBasketOnCheckout(basket.Items);

            var catalogItemsSpecification = new CatalogItemsSpecification(basket.Items.Select(item => item.CatalogItemId).ToArray());
            var catalogItems = await _itemRepository.ListAsync(catalogItemsSpecification);

            var items = basket.Items.Select(basketItem =>
            {
                var catalogItem = catalogItems.First(c => c.Id == basketItem.CatalogItemId);
                var itemOrdered = new CatalogItemOrdered(catalogItem.Id, catalogItem.Name, _uriComposer.ComposePicUri(catalogItem.PictureUri));
                var orderItem = new OrderItem(itemOrdered, basketItem.UnitPrice, basketItem.Quantity);
                return orderItem;
            }).ToList();

            var order = new Order(basket.BuyerId, shippingAddress, items);

            await _orderRepository.AddAsync(order);
        }
    }
}

被注入到OrderService的构造函数中。

OrderRepository 实现 中定义基础架构层

private readonly IAsyncRepository<Order> _orderRepository;

基础结构类 OrderRepository 遵循在应用程序核心层中定义的 IOrderInterface 合同。 IOrderRepository还是从 IAsyncRepository 派生而来的,也在应用程序核心层中定义。

我想他们之所以在 OrderService 中使用IAsyncRepository而不是IOrderRepository的原因是,到目前为止,OrderService方法仅访问由基本接口IAsyncRepository定义的方法。

但是想法仍然是相同的: “应用核心”层中的所有内容都应仅依赖于同一层中的内容 。然后在运行时通过依赖项注入来注入具体的实现。但是,应用程序核心层本身不需要知道基础结构层中存在的“真实”实现。

如果您采用这种方法,则声明

...应用程序核心位于中心,而外层则根据“依赖关系”指向内部。

仍然是正确的,因为外层取决于Application Core的类和接口,而Application Core仅取决于-Application Core。