我偶然发现了一些代码,我很好奇为什么会这样。
有两个构造函数,主要一个在代码中调用,第二个用于测试依赖注入。第二个构造函数接受了一个函数,该函数返回对象而不是对象本身的实例。
MainConstructor()
:this(() => Factory.Current.GetInstance<IQueryService>()){
}
SecondConstructor(Func<IQueryService> getQueryService){
}
我很好奇你传递函数而不是实例所带来的好处。
答案 0 :(得分:1)
做这样的事情有几个可能的好处:
答案 1 :(得分:0)
使用Func<T>
允许延迟创建产品,这对于可选的依赖项非常有用 - 例如,其中一个类方法可能如下所示:
public void SomeMethod()
{
if(someCondition)
{
IQueryService service = this.getQueryService();
service.Execute():
}
}
如果IQueryService
创建成本高,如果someCondition
永远不会评估为真,则可以提高效率。
答案 2 :(得分:0)
在这种情况下,Func<IQueryService>
实际上是一个伪装的抽象工厂。所以问题确实是:“你为什么要使用工厂而不是注入对象?”
当这样的实例的生命周期对消费者很重要时,您需要使用工厂,您需要控制该实例的生命周期,或者创建实例的代价很高。这方面的好例子是对象实现IDisposable
时。一次性物品通常需要明确控制。
我个人并不喜欢将Func<T>
个委托作为工厂使用,因为它会使您的代码不那么明确。让这个类依赖于Func<IQueryService>
,而不是依赖于IQueryServiceFactory
。这使您的代码更加明确。当然,这种方法的缺点是你必须编写更多代码(不多,但仍然如此)。
第二个构造函数使用依赖注入模式。但是,第一个构造函数是Poor Man's DI的示例。这是一种允许为单元测试注入依赖项的方法,但是节省了为生产代码使用依赖注入框架的需要。这种方法的缺点是需要依赖容器(在您的情况下为Factory
类),这种模式称为Service Locator。另一个缺点是它使一个类所需的依赖性不太明显。