服务和工厂之间的 IOC 容器循环依赖

IOC Container Circular Dependency Between Service and Factory

我有以下 classes/interfaces:

public class DataExpressionViewModelFactory : IDataExpressionViewModelFactory
{
    private readonly IDataExpressionService DataExpressionService;

    public DataExpressionViewModelFactory(IDataExpressionService dataExpressionService)
    {
        DataExpressionService = dataExpressionService;
    }

    public DataExpressionViewModel Create(DatabaseTableColumn column)
    {
        return new DataExpressionViewModel(DataExpressionService, column);
    }
}

public class DataExpressionService : IDataExpressionService
{
    private readonly IDataExpressionViewModelFactory DataExpressionViewModelFactory;

    ...
}

使用IOC容器(Microsoft.Extensions.DependencyInjection),它们之间存在循环依赖。 IDataExpressionViewModelFactory 需要 IDataExpressionService,反之亦然。

IDataExpressionViewModelFactory 创建 DataExpressionViewModels,传入 IDataExpressionServiceDataExpressionViewModels 使用 IDataExpressionService 来验证数据表达式字符串(用户输入)并从中进一步创建 DataExpressionViewModels,因为表达式可以相互嵌套(递归模型)。

有没有办法解决循环依赖?

重构应用程序使 IDataExpressionViewModel 成为一个模型 (IDataExpression),并将服务拆分为“编写器”服务和“对象创建”服务,从而消除了循环依赖,我通过阅读 delegate factories.

找到了一个适用于原始设计的解决方案

我使用委托作为其他实体的工厂,但我实际上有两个构造函数用于这个特定的实体,所以使用工厂 class 代替。现在了解委托工厂,我会说我原始设计中的代码味道(或其中之一)是在工厂本身内实例化服务。

要使用委托工厂移除循环依赖:

委托工厂Class

public delegate IDataExpressionViewModel CreateDataExpressionViewModel(DatabaseTableColumn column);
public delegate IDataExpressionViewModel CreateDataExpressionViewModelWithExpression(DatabaseTableColumn column, string expression);

public class DataExpressionViewModelDelegateFactory
{
    public readonly CreateDataExpressionViewModel;
    public readonly CreateDataExpressionViewModelWithExpression

    public DataExpressionViewModelDelegateFactory(
        CreateDataExpressionViewModel createDataExpressionViewModel,
        CreateDataExpressionViewModelWithExpression createDataExpressionViewModelWithExpression
    )
    {
        CreateDataExpressionViewModel = createDataExpressionViewModel;
        CreateDataExpressionViewModelWithExpression = createDataExpressionViewModelWithExpression;
    }
}

IOC 实现(在 App.xaml.cs 中)

services.AddTransient((provider) => new DataExpressionViewModelDelegateFactory(
    new CreateDataExpressionViewModel(
        (column) => new DataExpressionViewModel(
            provider.GetRequiredService<IDataExpressionService>(),
            column
        )
    ),
    new CreateDataExpressionViewModelWithExpression(
        (column, expression) => new DataExpressionViewModel(
            provider.GetRequiredService<IDataExpressionService>(),
            column,
            expression
        )
    )
));

委托工厂不依赖于服务,因为对象创建对服务的依赖性在创建时由 ServiceProvider 解析,因此依赖性被移除。

根据我链接的文章,如果需要很多委托并且变得太麻烦,您还可以在工厂 class 中使用 Func 而不是为每个方法创建特定的委托。