避免洋葱架构中的跨项目依赖

时间:2019-11-27 15:26:42

标签: c# architecture dependencies inversion-of-control onion-architecture

我有一个遵循此图的洋葱架构:

每个项目都通过接口连接到“中心”。

现在,我处于付款网关需要存储一些数据的情况。如果它可以访问数据库,那将是惊人的,但是我意识到我无法直接连接它们,这会破坏“洋葱”结构! (还有IoC原则!)

因此,似乎解决方案是创建一个我将在持久性中实现的接口,并将该接口传递给PaymentGateway。这将允许它保存自己的东西。但是此接口可能必须非常特定(即void SavePaymentGatewayCustomer(Customer customer);void SavePaymentGatewayCustomerPaymentMethod(PaymentMethod paymentMethod);,对我来说,这也打破了IoC,因为Persistence和“中心”都知道太多有关PaymentGateway的信息。

每个人迟早都会遇到一个问题,我想知道您是如何解决该问题的。


其他信息:

解决方案的结构是:

接口在“ AbstractionLayer”项目中定义,如下所示:

public interface IUsersPersistenceHandler : IDisposable
{
    /// <summary> Gets the user. </summary>
    /// <param name="id">The user identifier.</param>
    Result<IUser> GetUser(string id);

    ...
}

这些接口然后由外围项目实现:

public sealed class VolatileUserPersistenceHandler : IUsersPersistenceHandler
{
    private readonly Dictionary<string, Individual> _individuals;
    private readonly Dictionary<string, Organization> _organizations;

    /// <inheritdoc />
    public Result<IUser> GetUser(string id) { ... }
    ...
}

通过依赖注入,将实现注入到API级别,这样就不了解外部项目,而只知道接口(通过这种方式,数据库持久性可以轻松地与易失性持久性交换。或可以用另一网关代替支付网关,而不必重写所有内容)。

这是简单的情况。当PaymentGateway需要能够存储/检索自己的信息时,就会出现问题。

让我们说PaymentGateway有自己的用户定义。现在,我们要将我们的用户(在CORE中)与网关的用户相关联,并希望将信息保存在某处。
例如,PaymentGateway中的用户有一个string GatewayIdstring CustomerId,我们需要将其存储在某个地方。

请记住这种情况:CORE不想了解有关细节实现的任何信息!它只知道接口知道什么。
enter image description here

1 个答案:

答案 0 :(得分:2)

洋葱体系结构描述了应用。洋葱以外的系统是 other 应用程序。

  • 数据库在另一个进程中运行,通常在另一台计算机上
  • 邮件系统在另一个进程中运行,通常在另一台计算机上
  • 我假设付款网关在另一个过程中运行,通常在互联网上的其他地方
  • 依此类推...

支付网关可能具有持久性需求,但这应该与相关应用程序使用的持久性引擎无关。

如果以某种方式,您使用洋葱体系结构构建的应用程序需要将支付网关中的某些数据保留在其 持久性系统中,则这是 的责任。那么,在那种情况下,必须在 Core 中(或在下一层的“ controller”层中)处理一些应用程序代码。

详细了解洋葱架构和依赖注入here