项目
版本

Autofac .NET Core 集成

.NET Core 配备了一个符合规范的容器,即 Microsoft.Extensions.DependencyInjectionAutofac.Extensions.DependencyInjection 包实现了这些抽象,以通过 Autofac 提供依赖注入。

ASP.NET Core 的集成非常相似,因为整个框架已经统一了围绕依赖注入的抽象。我们的 ASP.NET Core 集成文档中有关于 ASP.NET Core(以及托管应用程序)使用特定主题的更多信息。

快速入门

要通过 Microsoft.Extensions.DependencyInjection 包在 .NET Core 应用程序中利用 Autofac:

  • 从 NuGet 引用 Autofac.Extensions.DependencyInjection 包。
  • 在应用程序启动时(例如,在 ProgramStartup 类中)...
    • 使用框架扩展方法在 IServiceCollection 中注册服务。
    • 将注册的服务填充到 Autofac 中。
    • 添加 Autofac 注册和覆盖。
    • 构建容器。
    • 使用容器创建 AutofacServiceProvider
public class Program
{
    public static void Main(string[] args)
    {
        // Microsoft.Extensions.DependencyInjection.ServiceCollection
        // 提供了其他 .NET Core 库提供的注册服务的扩展方法。
        var serviceCollection = new ServiceCollection();

        // Microsoft.Extensions.Logging 包提供了此一行代码来添加日志服务。
        serviceCollection.AddLogging();

        var containerBuilder = new ContainerBuilder();

        // 在将所有内容注册到 ServiceCollection 后,调用 Populate 将这些注册项带入 Autofac。
        // 这就像遍历集合中的项目列表并将其添加到 Autofac 中一样。
        containerBuilder.Populate(serviceCollection);

        // 对 Autofac 进行注册。顺序很重要!
        // 如果您在调用 Populate 之前进行注册,则 ServiceCollection 中的注册将覆盖 Autofac 注册。
        // 如果您在 Populate 之后进行注册,则 Autofac 注册将覆盖。您可以选择在 Populate 之前或之后进行注册。
        containerBuilder.RegisterType<MessageHandler>().As<IHandler>();

        // 创建新的 AutofacServiceProvider 使容器可用,以便您的应用可以使用 Microsoft 的 IServiceProvider 接口,从而使用这些抽象而不是直接绑定到 Autofac。
        var container = containerBuilder.Build();
        var serviceProvider = new AutofacServiceProvider(container);
    }
}

您不必使用 Microsoft.Extensions.DependencyInjection。 如果您不是编写需要它的 .NET Core 应用程序,或者您不使用其他库提供的任何依赖注入扩展,您可以直接使用 Autofac。您可能只需要调用 Populate() 方法,而不需要 AutofacServiceProvider。根据您的应用需求选择合适的部分。

作为根使用的子范围

在复杂的应用中,您可能希望将使用 Populate() 注册的服务保留在子生存周期范围中。例如,一个自托管 ASP.NET Core 组件的应用可能希望将 MVC 注册项等隔离到主容器之外。Populate() 方法提供重载版本,允许您指定一个标记的子生存周期范围,该范围应作为包含项目的 “容器”。

注意
如果您使用此功能,将无法使用 ASP.NET Core 支持的 IServiceProviderFactory{TContainerBuilder}ConfigureContainer 支持)。这是因为 IServiceProviderFactory{TContainerBuilder} 假设它在根级别工作。

public class Program
{
    private const string RootLifetimeTag = "MyIsolatedRoot";

    public static void Main(string[] args)
    {
        var serviceCollection = new ServiceCollection();
        serviceCollection.AddLogging();

        var containerBuilder = new ContainerBuilder();
        containerBuilder.RegisterType<MessageHandler>().As<IHandler>();
        var container = containerBuilder.Build();

        using (var scope = container.BeginLifetimeScope(RootLifetimeTag, b =>
        {
            b.Populate(serviceCollection, RootLifetimeTag);
        }))
        {
            // 此服务提供程序将访问全局单例和注册项,但对在服务集合中注册的项目来说,“单例”将在这个子范围下“根植”,对应用程序的其他部分不可用。

            // 显然,处于 using 块中并不太有用,因此您可能会在应用程序启动时创建范围,在整个应用程序生命周期中保留它,并在应用程序关闭时手动自行处理其销毁。
            var serviceProvider = new AutofacServiceProvider(scope);
        }
    }
}
在本文档中