14

我对使用 Autofac 还是很陌生,我在文档和示例中错过的一件事是如何轻松地从 Web 应用程序的不同位置访问配置的容器。

我知道我可以使用 Autofac 控制器工厂来自动解析控制器的构造函数注入依赖项,但是您可能需要解决尚未注入的其他内容呢?

有没有我不知道的明显模式?

谢谢!

4

5 回答 5

32

Autofac“方式”是有一个IContext构造函数参数。Autofac 将注入一个可用于解析类型的对象。

上下文通常是幕后的容器,IContainer实现IContext接口,但IContext仅限于解析。

我知道容器不应该被“过度使用”,但是作为 OP,我有需要解析提前不知道的类型的类(因此不能用作构造函数参数)。我发现在这些情况下很有用,将容器视为可用于解析其他服务的另一个服务,并像任何其他服务一样注入它。

如果您觉得使用 IContext 会将您绑定到 Autofac,并且您需要使用自己的接口对其进行抽象,那么这只是在IContext您的容器中注册一个包装类的问题。

更新:在 Autofac 2 中,IContext被称为IComponentContext.

于 2009-07-20T16:16:41.007 回答
12

首先尽量不要过度使用 IoC 容器。它非常适合“连接”控制器、视图和服务,但是需要在运行时创建的对象应该由工厂对象而不是容器创建。否则,您将通过您的代码获得 Container.Resolve 调用,并将其绑定到您的容器。这些额外的依赖破坏了使用 IoC 的目的。在大多数情况下,我只需在应用程序的顶层解决一两个依赖项即可。然后 IoC 容器将递归地解决大多数依赖项。

当我在程序的其他地方需要容器时,这是我经常使用的一个技巧。

public class Container : IContainer
{
    readonly IWindsorContainer container;

    public Container()
    {
        // Initialize container
        container = new WindsorContainer(new XmlInterpreter(new FileResource("castle.xml")));

        // Register yourself
        container.Kernel.AddComponentInstance<IContainer>(this);
    }

    public T Resolve<T>()
    {
        return container.Resolve<T>();
    }
}

我将容器包装在这样的 Container 类中。它将自己添加到构造函数中的包装容器中。现在,需要容器的类可以注入 IContainer。(该示例适用于温莎城堡,但它可能适用于 AutoFac)

于 2009-03-13T21:59:28.293 回答
8

让 IOC 容器在全球范围内可用并不是最佳实践。甚至不鼓励通过容器

如果无法使用依赖注入(您需要在创建组件后创建\请求对象),那么您可以:

  1. 使用手工编码的工厂(工厂被注入到组件中,组件使用工厂创建其他对象)
  2. 在 Autofac 2 中使用 Autofac委托工厂新的自动生成工厂
于 2009-11-10T06:51:44.787 回答
6

Peter Lillevold 上面的回答是正确的——您可以通过依赖 IContext 接口从任何组件访问容器。

如果您确实需要实际的容器引用,请参阅 Autofac.Integration.Web.IContainerProviderAccessor。

于 2009-08-01T20:18:10.277 回答
1

执行此操作的常用方法是将容器存储在全局应用程序类的静态变量中。

于 2009-03-13T21:52:29.107 回答