当我转向dependency injection时,使用语句会发生什么

我目前正在使用以下代码:

public class MyProvider { public MyProvider() { } public void Fetch() { using (PopClient popClient = new PopClient()) { .... } } } 

因为我希望能够对Fetch方法进行unit testing,并且由于我无法模拟PopClient,所以我创建了一个接口和一个调用PopClient的包装类。 我的更新代码如下:

 public class MyProvider { private readonly IPopClient popClient; public MyProvider(IPopClient popClient) { this.popClient = popClient; } public void Fetch() { using (var pop3 = popClient) { .... } } } 

我使用Ninject进行dependency injection,我不太确定using语句在更新的代码中会产生什么样的影响,因为Ninject已经创建了一个PopClient实例并将其注入到构造函数中。

using语句是否会处理pop3对象并将popClient对象单独保留,以便Ninject可以处理它或者using语句是否会干扰Ninject?

在这种情况下,正确的方法是什么? 任何见解都会非常有帮助。

pop3变量将被赋予与popClient具有的IPopClient对象相同的引用,因此当using语句结束时,本地变量和实例变量引用的对象将是Dispose()d,可能将其置于不一致状态供进一步使用。

如果你想使用IPopClient多个实例,每个Fetch()调用一个,你应该做的是注入一个“工厂方法”:

 public class MyProvider { private readonly Func createPopClient; public MyProvider(Func popClientFactory) { this.createPopClient = popClientFactory; } public void Fetch() { using (var pop3 = createPopClient()) { .... } } } 

现在,当您调用Fetch() ,它将执行工厂方法,该方法将返回对IPopClient的新引用,该引用可以在不影响对该方法的任何其他调用的情况下使用然后处理。

AutoFac支持为注册类型注入工厂方法而无需任何额外的设置(因此,我认为它的名称); 我相信在配置Ninject容器时,您需要显式注册“getter”作为给定返回类型的工厂方法(可以像lambda ()=>new PopClient()一样简单,也可以使用容器的解决方法)。

设置绑定时,声明范围:

https://github.com/ninject/ninject/wiki/Object-Scopes

Ninject将对它为您创建的对象调用dispose,因此请确保在您提供给Ninject处理的任何对象中编写dispose方法。