...看起来架构核心具有正在作为依赖项实现基础架构的 repos,这不是矛盾的吗?
您在这里缺少的是接口的使用。让我们看看应用程序核心层的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只有对接口的依赖应用程序核心。
比如有
private readonly IAsyncRepository<Order> _orderRepository;
注入到OrderService的构造函数中。
OrderRepository的实现在infrastructure层中定义:
namespace Microsoft.eShopWeb.Infrastructure.Data
{
public class OrderRepository : EfRepository<Order>, IOrderRepository
{
public OrderRepository(CatalogContext dbContext) : base(dbContext)
{
}
public Task<Order> GetByIdWithItemsAsync(int id)
{
return _dbContext.Orders
.Include(o => o.OrderItems)
.Include($"{nameof(Order.OrderItems)}.{nameof(OrderItem.ItemOrdered)}")
.FirstOrDefaultAsync(x => x.Id == id);
}
}
}
基础设施类OrderRepository 遵循应用程序核心层中定义的IOrderInterface 契约。 IOrderRepository 再次派生自 IAsyncRepository,它也在应用程序核心层中定义。
我猜他们在 OrderService 中使用 IAsyncRepository 而不是 IOrderRepository 的原因是,现在 OrderService 方法只访问由基本接口 IAsyncRepository 定义的方法。
但想法保持不变:应用程序核心层中的所有内容都应仅依赖于同一层中的内容。具体实现是通过依赖注入在运行时注入的。但应用程序核心层本身并不需要了解基础设施层中的“真实”实现。
如果你遵循这种方法,那么声明
...应用程序核心位于中心,外层根据“依赖关系”指向内部。
仍然如此,因为外层依赖于应用程序核心的类和接口,而应用程序核心仅依赖于应用程序核心。