继this讨论之后,我还有一些遗留代码,而不是正确地做了DI已经通过应用程序的容器,我认为这是因为一些通用/工厂/动态代码意味着他们什么时候这样做,他们更容易通过容器而不是重写整个系统!
然后,他们在需要时从容器实例中获得所需的内容。即。public class SomeStageInAPipeline :
{
private readonly IBlobAccessClient _blobAccessClient;
public SomeStageInAPipeline (Container container)
{
_blobAccessClient = container.GetInstance<IBlobAccessClient>();
}
这是好的,直到我们有条件地注册实例的场景,即
container.RegisterConditional(typeof(IBlobAccessClient),
Lifestyle.Singleton.CreateRegistration(
() => new BlobAccessClient(srcConnectionString), container),
c => c.Consumer.Target.Parameter.Name.Contains("src"));
container.RegisterConditional(typeof(IBlobAccessClient),
Lifestyle.Singleton.CreateRegistration(
() => new BlobAccessClient(destConnectionString), container),
c => c.Consumer.Target.Parameter.Name.Contains("dest"));
我可以设置一个默认值,即
container.RegisterConditional(typeof(IBlobAccessClient),
Lifestyle.Singleton.CreateRegistration(
() => new BlobAccessClient(srcConnectionString), container),
c => c.Handled == false);
适用于GetInstance(<IBlobAccessClient>)
的现有请求,但我不知道如何访问其他“dest”实例,或者它是否可能。
更新我希望能够做的是:
public class SomeStageInAPipeline :
{
private readonly IBlobAccessClient _srcBlobAccessClient;
private readonly IBlobAccessClient _destBlobAccessClient;
public SomeStageInAPipeline (Container container)
{
_srcBlobAccessClient = container.GetInstance<IBlobAccessClient>();
// obviously the below just gets me the default instance
_destBlobAccessClient = container.GetInstance<IBlobAccessClient>();
}
答案 0 :(得分:2)
根据其背景,注册是有条件的。但是,当您直接从Container
解决时,您将丢失所有可能的上下文信息。已解析的类型将成为新的根类型。这是直接注入Container
为really bad idea的众多原因之一。
您可以注入某种Func<string, IBlobAccessClient>
委托,但由于您已经对SomeStageInAPipeline
进行了更改,因此直接重构为构造函数注入,如下所示:
public class SomeStageInAPipeline
{
private readonly IBlobAccessClient _srcBlobAccessClient;
private readonly IBlobAccessClient _destBlobAccessClient;
public SomeStageInAPipeline(
IBlobAccessClient srcBlobAccessClient,
IBlobAccessClient destBlobAccessClient)
{
_srcBlobAccessClient = srcBlobAccessClient;
_destBlobAccessClient = destBlobAccessClient;
}
}
当您从SomeStageInAPipeline
解析Container
时,通过调用GetInstance<SomeStageInAPipeline>()
或将其注入消费者,Simple Injector将为您构建包含这些条件的预期对象图。
<强>更新强>:
如果此时无法更改SomeStageInAPipeline
的构造函数签名,请考虑将IBlobAccessClient
参数移动到参数对象中并从Container
解析该参数对象:< / p>
public sealed class BlobAccessClients
{
public readonly IBlobAccessClient Src;
public readonly IBlobAccessClient Dest;
public BlobAccessClients(IBlobAccessClient src, IBlobAccessClient dest)
{
this.Src = src;
this.Dest = dest;
}
}
这允许您将SomeStageInAPipeline
更改为以下内容:
public class SomeStageInAPipeline
{
private readonly IBlobAccessClient _srcBlobAccessClient;
private readonly IBlobAccessClient _destBlobAccessClient;
public SomeStageInAPipeline (Container container)
{
var clients = container.GetInstance<BlobAccessClients>();
_srcBlobAccessClient = clients.Src;
_destBlobAccessClient = clients.Dest;
}
}