Asp.net Autofac在web应用程序中,应将容器存储在何处以便于访问?

Asp.net Autofac在web应用程序中,应将容器存储在何处以便于访问?,asp.net,dependency-injection,inversion-of-control,autofac,Asp.net,Dependency Injection,Inversion Of Control,Autofac,我对使用Autofac还是相当陌生的,在文档和示例中我遗漏了一件事,那就是如何使从web应用程序的不同位置轻松访问已配置的容器 我知道我可以使用Autofac控制器工厂自动解析控制器的构造函数注入依赖项,但是您可能需要解析尚未注入的其他内容 有没有一个我不知道的明显模式 谢谢大家! 通常的方法是将容器存储在全局应用程序类中的静态变量中。首先,不要过度使用IoC容器。它非常适合“连接”控制器、视图和服务,但是需要在运行时创建的对象应该由工厂对象而不是容器创建。否则您将获得Container.Res

我对使用Autofac还是相当陌生的,在文档和示例中我遗漏了一件事,那就是如何使从web应用程序的不同位置轻松访问已配置的容器

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

有没有一个我不知道的明显模式


谢谢大家!

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

首先,不要过度使用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>();
    }
}
公共类容器:IContainer
{
只读IWindsorContainer;
公共容器()
{
//初始化容器
容器=新的WindsorContainer(新的xml解释器(新的文件资源(“castle.xml”));
//注册
container.Kernel.AddComponentInstance(this);
}
公共事务解决方案
{
返回container.Resolve();
}
}
我将容器包装在一个容器类中,如下所示。它将自己添加到构造函数中的包装容器中。现在,需要容器的类可以注入IContainer。(示例适用于Castle Windsor,但可能适用于AutoFac)

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

上下文通常是幕后的容器,
IContainer
实现
IContext
接口,尽管
IContext
仅限于执行解析

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

如果您觉得使用IContext会将您绑定到Autofac,并且您需要使用自己的接口来抽象它,那么只需在容器中注册一个
IContext
包装类即可


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

Peter Lillevold的上述响应是正确的-您可以通过依赖IContext接口从任何组件访问容器


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

全球提供IOC容器不是最佳做法。甚至

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

  • 使用手动编码工厂(工厂被注入组件,组件使用工厂创建其他对象)
  • 使用Autofac或

  • 啊,但是要小心你存放的容器!您不必访问应用程序容器,这是肯定的!为什么不注入工厂?@TrueWill-…区别在于?这里的线索是,并不总是(特别是对于没有考虑DI的遗留代码)编译时未知的所需服务类型。因此,需要一个“非强”类型的工厂。IContext只是一个工厂,它可以生成您试图解析的类型的实例。似乎是autofac 1.0的一个功能,现在v2BTW中缺少了这个问题。这个问题是在MVC处于版本2时提出的。在MVC 3中,
    DependencyResolver.Current
    是所有您需要的,无论您使用的是Autofac还是其他什么。huzzah,因为没有将容器用作服务定位器