C# IOC容器的最佳实践

C# IOC容器的最佳实践,c#,inversion-of-control,unity-container,C#,Inversion Of Control,Unity Container,我正在使用Unity IOC容器,我只是想知道访问多个类的容器的最佳方式是什么 是否每个类都应该有一个IUnityContainer成员,然后由构造函数传入容器?是否应该有一个带有IOC容器的单例类 asp.net开发怎么样 有人能给我指路吗?谢谢 您可以在容器本身中注册容器,并像其他依赖项属性一样将其注入,如下所示: IUnityContainer container = new UnityContainer(); container.RegisterInstance<IUnityCon

我正在使用Unity IOC容器,我只是想知道访问多个类的容器的最佳方式是什么

是否每个类都应该有一个IUnityContainer成员,然后由构造函数传入容器?是否应该有一个带有IOC容器的单例类

asp.net开发怎么样


有人能给我指路吗?谢谢

您可以在容器本身中注册容器,并像其他依赖项属性一样将其注入,如下所示:

IUnityContainer container = new UnityContainer();
container.RegisterInstance<IUnityContainer>(container);
因此,每当解析/构建此类类的实例时,就会注入容器


这是更灵活的,因为它适用于同一应用程序中的多个容器,这在单例模式中是不可能的。

如果所有对象都需要对容器的引用,那么您应该考虑重新编写一些代码。尽管仍然比到处调用new更可取,但它仍然分散了在代码中构建对象图的责任。对于这种用法,我觉得它更像是一个ServiceLocator,而不是IoC容器。

另一个选项是使用,尽管它可能是一个无意义的间接寻址,你可以使用
ServiceLocator.Current
作为所有类都知道的实例

我在我的博客上有一篇关于这个主题的帖子,我在这里使用了一些类似于t3mujin答案的东西。您可以随意使用它(不必担心它与sharepoint相关……这无关紧要):


将IOC容器放在流程中的最高级别/入口点,并使用它在其下的所有内容中注入依赖项。

因此,不建议将整个容器注入类中或使用应用程序范围的静态IOC服务定位器

您希望能够从类的构造函数(我们称之为Foo)中看到它正在使用什么样的服务/对象来完成工作。这提高了清晰度、可测试性和可消保真性

假设Foo只需要电子邮件服务,但我将整个容器传递给它,并且在代码的某个地方,电子邮件服务从容器中得到解析。在这种情况下,将很难遵循。相反,最好将电子邮件服务直接注入到状态Foo的依赖项中

如果Foo需要创建电子邮件服务的多个实例,最好创建并注入一个EmailServiceFactory(通过IoC容器),它将动态创建所需的实例

在后一种情况下,Foo的依赖项仍然尽可能具体地表示出来——只有EmailServiceFactory可以创建的依赖项。如果我注入整个容器,就不清楚它提供的服务是Foo的确切依赖项

现在,如果我以后想提供不同的电子邮件服务实例,我会在EmailServiceFactory中交换它。如果它创建的所有服务都需要交换(例如,在测试期间),我也可以交换整个工厂

因此,以创建一个额外的类(工厂)为代价,我得到了更干净的代码,并且不必担心使用全局静态时可能出现的奇怪错误。此外,当提供模拟用于测试时,我确切地知道它需要什么样的模拟,而不必模拟整个容器的类型

这种方法还有一个优点,即现在,当一个模块被初始化时(仅适用于Prism/模块化),它不必注册它向IoC容器提供的所有类型的对象。相反,它可以注册它的ServiceFactory,然后由它提供这些对象

需要明确的是,模块的初始化类(实现IModule)仍应在其构造函数中接收应用程序范围的IoC容器,以便提供其他模块使用的服务,但容器不应侵入模块的类


最后,我们这里还有一个很好的例子,说明了一个额外的间接层如何解决问题。

我正在使用的应用程序使用Com+进行所有数据访问。我一直在使用IOC容器来实例化这些对象,所以如果需要的话,我可以在测试中加入双重测试。因此,我必须将所有数据访问限制在一个类中,而且IOC容器也很难做到。这本书如是说。假设Foo有一个方法=>Foo.sendeMail(T值)。您需要实例化一个IEmail实例来匹配它。在这种情况下,您可以创建一个复杂的工厂类,或者只注入容器本身。非常好的建议。我认为您甚至不必创建新的factory类,只需使用“Func sthFactory”作为注入参数,Unity就会处理它。稍后您可以调用var sth=sthFactory()@JarekKardas你是对的,Unity的新版本支持这一点。我回答问题时的当前版本没有该功能;)。Unity容器自动向IUnityContainer注册,young grass hopper.IOC容器自行解析。。。谁会砰的一声叹息。。重新发明轮子有多有趣?那也是正方形的。看看这个。
private IUnityContainer unityContainer;
[Dependency]
public IUnityContainer UnityContainer
{
    get { return unityContainer; }
    set { unityContainer = value; }
}