06、NetCore2.0依赖注入(DI)之整合Autofac
除了使用NetCore2.0系统的依赖注入(DI)框架外,我们还可以使用其他成熟的DI框架,如Autofac、Unity等。只要他们支持IServiceProvider接口规范。我们这次尝试使用Autofac来替代系统DI框架。
------------------------------------------------------------------------------------------------------------
写在前面:这是一个系列的文章,总目录请移步:NetCore2.0技术文章目录
------------------------------------------------------------------------------------------------------------
一、安装支持NetCore2.0的Autofac包
使用VS2017创建一个空的MVC项目,准备在这个项目中整合Autofac
1.安装核心包
install-package autofac
2.安装扩展包
install-package Autofac.Extensions.DependencyInjection
就是它支持了IServiceProvider接口规范:
using System;
using Microsoft.Extensions.DependencyInjection;
namespace Autofac.Extensions.DependencyInjection
{
public class AutofacServiceProvider : IServiceProvider, ISupportRequiredService
{
public AutofacServiceProvider(IComponentContext componentContext);
public object GetRequiredService(Type serviceType);
public object GetService(Type serviceType);
}
}
二、在Web应用中整合Autofac
系统DI框架入口是Startup.ConfigureServices方法:
public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddSingleton<IRun, Run>(); return services.BuildServiceProvider(); }
我们可以看出,这个方法配置了IServiceProvider的实现。那么,我们的整合方法就是用Autofac实现的IServiceProvider对象,替换系统的IServiceProvider。
public IContainer ApplicationContainer { get; private set; } public IServiceProvider ConfigureServices(IServiceCollection services) { var builder = new ContainerBuilder(); // 注入方式1:autofac将全盘接收 services.AddSingleton<IRun, Run>(); // 注入方式2: autofac自行注册 //builder.RegisterType<Run>().As<IRun>(); builder.Populate(services); this.ApplicationContainer = builder.Build(); return new AutofacServiceProvider(this.ApplicationContainer); }
可以看出,既可以用原有的方式注册服务,也可以用Autofac方式注册,最后Autofac会全盘接收管理。其中自定义的接口如下:
interface IRun { string Show(); } public class Run : IRun { public string Show() { return "奔跑吧,兄弟"; } }
下面我们在业务中调用这个接口,看是否成功。
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Run(async (context) => { await context.Response.WriteAsync(app.ApplicationServices.GetService<IRun>().Show()); }); }
运行效果是ok的^_^,不难体会到,接口的对扩展开放特点。