Autofac .NET Core 集成
.NET Core 配备了一个符合规范的容器,即 Microsoft.Extensions.DependencyInjection。Autofac.Extensions.DependencyInjection
包实现了这些抽象,以通过 Autofac 提供依赖注入。
与 ASP.NET Core 的集成非常相似,因为整个框架已经统一了围绕依赖注入的抽象。我们的 ASP.NET Core 集成文档中有关于 ASP.NET Core(以及托管应用程序)使用特定主题的更多信息。
快速入门
要通过 Microsoft.Extensions.DependencyInjection
包在 .NET Core 应用程序中利用 Autofac:
- 从 NuGet 引用
Autofac.Extensions.DependencyInjection
包。 - 在应用程序启动时(例如,在
Program
或Startup
类中)...- 使用框架扩展方法在
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);
}
}
}