应用层应该知道缓存机制,还是属于基础设施层?

Should application layer be aware of the caching mechanism, or could it belong to the infrastructure layer?

假设我有一个 API 端点,它需要一些产品数据才能正确处理请求。想象一下,有一些应用层服务必须处理合同(例如,让它成为一个查询)。应用层服务与一些外部提供者通信以获取产品信息。伪代码可能是这样的:

class ApplicationService
{
    IProductCache _productCache;
    IProductProvider _productProvider;

    public void Handle(Contract contract)
    {
        var products = _productCache.GetProducts();
    
        if (products == null)
        {
            products = _productProvider.GetProducts();
        }

        ...
    }
}

在这样的解决方案中,应用层知道有一些缓存机制,应用服务首先与缓存通信,然后与提供者通信。我们还可以将缓存机制封装在基础设施层(IProductProvider 实现所属)。我们会有这样的东西:

class ApplicationService
{
    IProductProvider _productProvider;

    public void Handle(Contract contract)
    {
        var products = _productProvider.GetProducts();
        ...
    }
}

class ProductsProvider : IProductProvider
{
    IProductCache _productCache;

    public Product[] GetProducts()
    {
        var cachedProducts = _productCache.GetProducts();
        
        if (cachedProducts not empty)
        {
            return cachedProducts;
        }
        
        // else communicate with external provider
        ...
    }
}

哪种方案更好更合适?两者的优缺点是什么?你能分享一下你对此的看法吗?在此先感谢您的帮助。

六边形架构指出应用程序是在同心层中形成的,引用向内。六边形应用程序的最外层是适配器层。适配器内部的下一层是端口层。最内层是业务逻辑。

端口充当业务逻辑(向内)和基础设施(向外)之间的边界。

将缓存添加到与产品持久性存储的通信是与​​产品存储通信的实现细节。它应该进入实现 IProductCache.GetProducts() 端口的适配器层。您应该将对 IProductCache 的引用放在 ProductProvider.

ApplicationService 不是注入缓存的好地方,因为该适配器负责与客户端的通信。缓存产品与与客户端的通信无关,而是与产品数据存储的通信。

但是,这会将缓存添加到需要产品列表的应用程序的每个部分。有时您可能需要强制通信并忽略缓存。在那种情况下,您应该为端口实现两个适配器,一个有缓存,另一个没有。然后配置依赖项注入,为每个用例注入正确的适配器。