![]() |
1
22
IMHO不建议将整个容器注入到类中,也不建议使用应用程序范围的静态IoC服务定位器。 您希望能够从类的构造函数(我们称之为Foo)中看到它正在使用什么样的服务/对象来完成工作。这提高了清晰度、可测试性和可消保真性。 假设Foo只需要电子邮件服务,但我将整个容器传递给它,并且在代码的某个地方,电子邮件服务从容器中得到解析。在这种情况下,将很难遵循。相反,最好将电子邮件服务直接注入到状态Foo的依赖项中。 如果Foo需要创建电子邮件服务的多个实例,最好创建并注入一个EmailServiceFactory(通过IoC容器),它将动态创建所需的实例。
现在,如果我以后想提供不同的电子邮件服务实例,我会在EmailServiceFactory中交换它。如果它创建的所有服务都需要交换(例如,在测试期间),我也可以交换整个工厂。 因此,以创建一个额外的类(工厂)为代价,我得到了更干净的代码,并且不必担心使用全局静态时可能出现的奇怪错误。此外,当提供模拟用于测试时,我确切地知道它需要什么样的模拟,而不必模拟整个容器的类型。 这种方法还有一个优点,即现在,当一个模块被初始化时(仅适用于Prism/模块化),它不必注册它向IoC容器提供的所有类型的对象。相反,它可以注册它的ServiceFactory,然后由它提供这些对象。 需要明确的是,模块的初始化类(实现IModule)仍应在其构造函数中接收应用程序范围的IoC容器,以便提供其他模块使用的服务,但容器不应侵入模块的类。 最后,我们这里有另一个很好的例子,说明了额外的间接层是如何解决问题的。 |
![]() |
2
14
将IOC容器放在流程中的最高级别/入口点,并使用它将依赖项注入到它下面的所有内容中。 |
![]() |
3
6
您可以在容器本身中注册容器,并像其他依赖项属性一样将其注入,如下所示:
因此,每当解析/构建此类类的实例时,就会注入容器。 这更灵活,因为它适用于同一应用程序中的多个容器,而单例模式不可能做到这一点。 |
![]() |
4
2
如果您的所有对象都需要对容器的引用,那么您应该重新编写一些代码。尽管仍然比到处调用new更可取,但它仍然分散了在代码中构建对象图的责任。这种用法让我觉得它更像是一个ServiceLocator,而不是IoC容器。 |
![]() |
5
0
另一个选择是使用
CommonServiceLocator
,尽管这可能是一个无意义的间接过程,但您可以使用
|
|
Robert King · Unity C#语法问题-转换位置 1 年前 |
![]() |
JBryanB · 如何从基本抽象类访问类属性 1 年前 |
|
law · 检查答案按钮的输入字符串格式不正确 2 年前 |
![]() |
i_sniff_ket · 在unity之外使用unity类 2 年前 |