ASP.Net Core 3.1 With Autofac ConfigureServices returning an System.IServiceProvider isn't supported.
前言
Autofac在ASP.Net Core3.0以后,集成方式有所调整。在ASP.Net Core2中我们一般是把Startup的ConfigureServices方法返回值类型改为IServiceProvider。我们可以先看一下部分代码:
1 public IServiceProvider ConfigureServices(IServiceCollection services) 2 { 3 4 services.AddMvc(); 5 //xxxxxx你的其他代码 省略........... 6 //用Autofac来替换IOC容器 返回值由 void 修改为 IServiceProvider 7 var containerBuilder = new ContainerBuilder(); 8 containerBuilder.RegisterModule<CustomAutofacModule>(); 9 containerBuilder.Populate(services); 10 var container = containerBuilder.Build(); 11 //将当前的容器保存起来,用于后续使用 12 AutofacHelper.Container = container; 13 return new AutofacServiceProvider(container); 14 }
完整代码可以参考我之前的开源项目:LJD.APP:https://github.com/jellydong/LJDAPP
CustomAutofacModule是把Autofac的配置单独写,不然都放在Startup中有点臃肿。
我们把这段代码Copy到ASP.Net Core3.1的项目中启动:
异常:
System.NotSupportedException:“ConfigureServices returning an System.IServiceProvider isn't supported.”
就是说,我们不能再这样修改返回值类型,
官网解释:您不能再
IServiceProvider从中返回ConfigureServices,也不能将服务提供者工厂添加到服务集合中。
那我们按照官方文档的方法修改一下。
建立ASP.Net Core3.1 Web项目
效果图

Services
创建完成后我们先创建文件夹Services,用来测试使用。
在Services文件夹下创建Iservice
1namespace DotNetCore3AutoFac.Services 2{ 3 public interface IService 4 { 5 string SayHi(); 6 } 7}
然后创建两个Iservice的实现类OneService、TwoService
1namespace DotNetCore3AutoFac.Services 2{ 3 public class OneService:IService 4 { 5 public string SayHi() 6 { 7 return "One Say Hi"; 8 } 9 } 10} 11 12 13namespace DotNetCore3AutoFac.Services 14{ 15 public class TwoService:IService 16 { 17 public string SayHi() 18 { 19 return "Two Say Hi"; 20 } 21 } 22}
Autofac
创建Autofac文件夹,在该文件夹下创建CustomAutofacModule
1using Autofac; 2using DotNetCore3AutoFac.Services; 3 4namespace DotNetCore3AutoFac.Autofac 5{ 6 public class CustomAutofacModule : Module 7 { 8 /// <summary> 9 /// AutoFac注册类 10 /// </summary> 11 /// <param name="builder"></param> 12 protected override void Load(ContainerBuilder builder) 13 { 14 builder.RegisterType<OneService>().As<IService>(); 15 } 16 } 17}
我们先用OneService去实现,当然,正常这里会有很多很多的代码~
修改Startup和Program
当然,需要安装Autofac的包:
Autofac&Autofac.Extensions.DependencyInjection
前序工作都完成了,我们来改最重要的,首先修改我们的Program,增加UseServiceProviderFactory(new AutofacServiceProviderFactory())
1namespace DotNetCore3AutoFac 2{ 3 public class Program 4 { 5 public static void Main(string[] args) 6 { 7 CreateHostBuilder(args).Build().Run(); 8 } 9 10 public static IHostBuilder CreateHostBuilder(string[] args) => 11 Host.CreateDefaultBuilder(args) 12 //改用Autofac来实现依赖注入 13 .UseServiceProviderFactory(new AutofacServiceProviderFactory()) 14 .ConfigureWebHostDefaults(webBuilder => 15 { 16 webBuilder.UseStartup<Startup>(); 17 }); 18 } 19} 20
然后我们修改Startup
1、增加属性
AutofacContainer2、增加方法
ConfigureContainer它在ConfigureServices之后运行3、给属性赋值(可选)
1using Autofac; 2using Autofac.Extensions.DependencyInjection; 3using DotNetCore3AutoFac.Autofac; 4using Microsoft.AspNetCore.Builder; 5using Microsoft.AspNetCore.Hosting; 6using Microsoft.Extensions.Configuration; 7using Microsoft.Extensions.DependencyInjection; 8using Microsoft.Extensions.Hosting; 9 10namespace DotNetCore3AutoFac 11{ 12 public class Startup 13 { 14 public Startup(IConfiguration configuration) 15 { 16 Configuration = configuration; 17 } 18 19 public IConfiguration Configuration { get; } 20 //autofac 新增 21 public ILifetimeScope AutofacContainer { get; private set; } 22 23 24 // This method gets called by the runtime. Use this method to add services to the container. 25 public void ConfigureServices(IServiceCollection services) 26 { 27 services.AddControllersWithViews(); 28 } 29 30 //autofac 新增 31 public void ConfigureContainer(ContainerBuilder builder) 32 { 33 // 直接用Autofac注册我们自定义的 34 builder.RegisterModule(new CustomAutofacModule()); 35 } 36 37 38 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 39 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 40 { 41 if (env.IsDevelopment()) 42 { 43 app.UseDeveloperExceptionPage(); 44 } 45 else 46 { 47 app.UseExceptionHandler("/Home/Error"); 48 // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 49 app.UseHsts(); 50 } 51 //autofac 新增 可选 52 this.AutofacContainer = app.ApplicationServices.GetAutofacRoot(); 53 54 55 app.UseHttpsRedirection(); 56 app.UseStaticFiles(); 57 58 app.UseRouting(); 59 60 app.UseAuthorization(); 61 62 app.UseEndpoints(endpoints => 63 { 64 endpoints.MapControllerRoute( 65 name: "default", 66 pattern: "{controller=Home}/{action=Index}/{id?}"); 67 }); 68 } 69 } 70} 71
验证
我们修改下HomeController

运行,断点看下结果是否正确

修改下实现类,也是正确的~

总结
其实很多官方文档都讲述了,因为自己近期打算把原来的项目LJD.APP:https://github.com/jellydong/LJDAPP升级到.Net Core 3.1上,当然是一个简化版本https://github.com/jellydong/Jelly.Simple。
所以不要怕英文,翻译插件那么好用,基本都能看懂的
当然Autofac的应用远不止这些,还有一个比原来好的就是可以实现AOP~
