关于清洁/洋葱架构,我有几个问题。我一直在阅读Microsoft文档,它指出应用程序核心在中间,而外层则在“依赖性”方面向内指向。
在这种情况下取决于它们到底是什么意思?当我想到依赖项时,我想到在类A内部实例化了类B,因此类A依赖于类B。但是,当我看一下eShopOnWeb存储库(https://github.com/dotnet-architecture/eShopOnWeb)时,它看起来就像架构核心具有将基础设施作为依赖项实施的回购协议,这不是矛盾的吗?
答案 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。