服务和工厂之间的 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
创建 DataExpressionViewModel
s,传入 IDataExpressionService
。 DataExpressionViewModel
s 使用 IDataExpressionService
来验证数据表达式字符串(用户输入)并从中进一步创建 DataExpressionViewModel
s,因为表达式可以相互嵌套(递归模型)。
有没有办法解决循环依赖?
重构应用程序使 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
而不是为每个方法创建特定的委托。
我有以下 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
创建 DataExpressionViewModel
s,传入 IDataExpressionService
。 DataExpressionViewModel
s 使用 IDataExpressionService
来验证数据表达式字符串(用户输入)并从中进一步创建 DataExpressionViewModel
s,因为表达式可以相互嵌套(递归模型)。
有没有办法解决循环依赖?
重构应用程序使 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
而不是为每个方法创建特定的委托。