如何将参数传递给依赖项通过 IoC 容器连接的 class?
How to pass parameter to a class whose dependencies are wired through IoC container?
我有一个 class 可以通过多种资源与网络一起工作。它的构造函数接收由 IoC 容器 (StructureMap) 在运行时解析的参数:
public NetworkWorker(IRetryService retryService, ILog log)
{ ... }
我需要的是控制此 class 在用例级别上使用的资源数量 - 例如,客户端 A 需要一次只允许一个操作的 NetworkWorker 实例,而客户端 B 需要一次 10 个操作。
目前这个数字在构造函数中是硬编码的。我看到的唯一方法是添加一个方法 void Configure(int resourceCount)
,NetworkWorker 的每个客户端将使用不同的值调用该方法。
或者我没有看到更好的方法?
class 可以做不同的事情,但是每个方法调用都需要一定数量的资源(Get/Send/etc
方法)。
P.S。这是一种已知技术(使用 Configure
方法)吗?如果是,它的名字是什么?像 'two-step initialization'?
我假设这个 NetworkWorker 有多个方法(否则你可以只向那个方法添加一个参数)。
你可以使用工厂模式:
public interface INetworkWorkerFactory
{
NetworkWorker Create(int numberOfResources);
}
public class NetworkWorkerFactory : INetworkWorkerFactory
{
private readonly IContainer _container;
public NetworkWorkerFactory(IContainer container)
{
_container = container;
}
public NewtorkWorker Create(int numberOfResources)
{
var retryService = _container.GetInstance<IRetryService>();
var log = _container.GetInstance<ILog>();
return new NewtorkWorker(retryService, log, numberOfResources);
}
}
(或者简单地注入所需的依赖项而不是容器)
然后简单地
private readonly INetworkWorkerFactory _networkWorkerFactory;
public C(INetworkWorkerFactory networkWorkerFactory)
{
_networkWorkerFactory = networkWorkerFactory;
}
public void M()
{
var networkWorker = _networkWorkerFactory.Create(10);
}
Autofac 为此使用 delegate factories。
其他容器具有提供自动生成的等效机制Abstract Factories - @ploeh has an awesome SO post aggregating examples。
您问题中的代码如下所示:
public delegate NetworkWorker Factory(IRetryService retryService);
public NetworkWorker(IRetryService retryService, ILog log)
{ ... }
消费者看起来像这样(从 Alex 的回答中偷来的)
readonly NetworkWorker.Factory _networkWorkerFactory;
public C(NetworkWorker.Factory networkWorkerFactory)
{
_networkWorkerFactory = networkWorkerFactory;
}
public void M()
{
var networkWorker = _networkWorkerFactory(10);
...
}
主要区别在于您没有为抽象工厂声明 interface
或 impl - delegate
是接口,而 Autofac 'just knows' 使其余的发生.
这种方法的另一个好处(除了代码减少之外)是将代码转换为 Pure DI)
的自然途径
我有一个 class 可以通过多种资源与网络一起工作。它的构造函数接收由 IoC 容器 (StructureMap) 在运行时解析的参数:
public NetworkWorker(IRetryService retryService, ILog log)
{ ... }
我需要的是控制此 class 在用例级别上使用的资源数量 - 例如,客户端 A 需要一次只允许一个操作的 NetworkWorker 实例,而客户端 B 需要一次 10 个操作。
目前这个数字在构造函数中是硬编码的。我看到的唯一方法是添加一个方法 void Configure(int resourceCount)
,NetworkWorker 的每个客户端将使用不同的值调用该方法。
或者我没有看到更好的方法?
class 可以做不同的事情,但是每个方法调用都需要一定数量的资源(Get/Send/etc
方法)。
P.S。这是一种已知技术(使用 Configure
方法)吗?如果是,它的名字是什么?像 'two-step initialization'?
我假设这个 NetworkWorker 有多个方法(否则你可以只向那个方法添加一个参数)。
你可以使用工厂模式:
public interface INetworkWorkerFactory
{
NetworkWorker Create(int numberOfResources);
}
public class NetworkWorkerFactory : INetworkWorkerFactory
{
private readonly IContainer _container;
public NetworkWorkerFactory(IContainer container)
{
_container = container;
}
public NewtorkWorker Create(int numberOfResources)
{
var retryService = _container.GetInstance<IRetryService>();
var log = _container.GetInstance<ILog>();
return new NewtorkWorker(retryService, log, numberOfResources);
}
}
(或者简单地注入所需的依赖项而不是容器) 然后简单地
private readonly INetworkWorkerFactory _networkWorkerFactory;
public C(INetworkWorkerFactory networkWorkerFactory)
{
_networkWorkerFactory = networkWorkerFactory;
}
public void M()
{
var networkWorker = _networkWorkerFactory.Create(10);
}
Autofac 为此使用 delegate factories。
其他容器具有提供自动生成的等效机制Abstract Factories - @ploeh has an awesome SO post aggregating examples。
您问题中的代码如下所示:
public delegate NetworkWorker Factory(IRetryService retryService);
public NetworkWorker(IRetryService retryService, ILog log)
{ ... }
消费者看起来像这样(从 Alex 的回答中偷来的)
readonly NetworkWorker.Factory _networkWorkerFactory;
public C(NetworkWorker.Factory networkWorkerFactory)
{
_networkWorkerFactory = networkWorkerFactory;
}
public void M()
{
var networkWorker = _networkWorkerFactory(10);
...
}
主要区别在于您没有为抽象工厂声明 interface
或 impl - delegate
是接口,而 Autofac 'just knows' 使其余的发生.
这种方法的另一个好处(除了代码减少之外)是将代码转换为 Pure DI)
的自然途径