ASP.Net Core 3.1 With Autofac ConfigureServices returning an System.IServiceProvider isn't supported.html
前言
Autofac在ASP.Net Core3.0之後,集成方式有所調整。在ASP.Net Core2中咱們通常是把Startup
的ConfigureServices
方法返回值類型改成IServiceProvider
。咱們能夠先看一下部分代碼:ios
public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddMvc(); //xxxxxx你的其餘代碼 省略........... //用Autofac來替換IOC容器 返回值由 void 修改成 IServiceProvider var containerBuilder = new ContainerBuilder(); containerBuilder.RegisterModule<CustomAutofacModule>(); containerBuilder.Populate(services); var container = containerBuilder.Build(); //將當前的容器保存起來,用於後續使用 AutofacHelper.Container = container; return new AutofacServiceProvider(container); }
完整代碼能夠參考我以前的開源項目:LJD.APP:https://github.com/jellydong/LJDAPPgit
CustomAutofacModule是把Autofac的配置單獨寫,否則都放在Startup中有點臃腫。github
咱們把這段代碼Copy到ASP.Net Core3.1的項目中啓動:web
異常:
System.NotSupportedException:「ConfigureServices returning an System.IServiceProvider isn't supported.」
c#
就是說,咱們不能再這樣修改返回值類型,app
官網解釋:您不能再
IServiceProvider
從中返回ConfigureServices
,也不能將服務提供者工廠添加到服務集合中。ide
那咱們按照官方文檔的方法修改一下。測試
創建ASP.Net Core3.1 Web項目
效果圖ui
Services
建立完成後咱們先建立文件夾Services
,用來測試使用。
在Services
文件夾下建立Iservice
namespace DotNetCore3AutoFac.Services { public interface IService { string SayHi(); } }
而後建立兩個Iservice
的實現類OneService
、TwoService
namespace DotNetCore3AutoFac.Services { public class OneService:IService { public string SayHi() { return "One Say Hi"; } } }
namespace DotNetCore3AutoFac.Services { public class TwoService:IService { public string SayHi() { return "Two Say Hi"; } } }
Autofac
建立Autofac
文件夾,在該文件夾下建立CustomAutofacModule
using Autofac; using DotNetCore3AutoFac.Services; namespace DotNetCore3AutoFac.Autofac { public class CustomAutofacModule : Module { /// <summary> /// AutoFac註冊類 /// </summary> /// <param name="builder"></param> protected override void Load(ContainerBuilder builder) { builder.RegisterType<OneService>().As<IService>(); } } }
咱們先用OneService
去實現,固然,正常這裏會有不少不少的代碼~
修改Startup
和Program
固然,須要安裝Autofac的包:
Autofac
&Autofac.Extensions.DependencyInjection
前序工做都完成了,咱們來改最重要的,首先修改咱們的Program
,增長UseServiceProviderFactory(new AutofacServiceProviderFactory())
namespace DotNetCore3AutoFac { public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) //改用Autofac來實現依賴注入 .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); } }
而後咱們修改Startup
一、增長屬性
AutofacContainer
二、增長方法
ConfigureContainer
它在ConfigureServices
以後運行三、給屬性賦值(可選)
using Autofac; using Autofac.Extensions.DependencyInjection; using DotNetCore3AutoFac.Autofac; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace DotNetCore3AutoFac { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } //autofac 新增 public ILifetimeScope AutofacContainer { get; private set; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); } //autofac 新增 public void ConfigureContainer(ContainerBuilder builder) { // 直接用Autofac註冊咱們自定義的 builder.RegisterModule(new CustomAutofacModule()); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } //autofac 新增 可選 this.AutofacContainer = app.ApplicationServices.GetAutofacRoot(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } } }
驗證
咱們修改下HomeController
運行,斷點看下結果是否正確
修改下實現類,也是正確的~
總結
其實不少官方文檔都講述了,由於本身近期打算把原來的項目LJD.APP:https://github.com/jellydong/LJDAPP升級到.Net Core 3.1上,固然是一個簡化版本https://github.com/jellydong/Jelly.Simple。
因此不要怕英文,翻譯插件那麼好用,基本都能看懂的
固然Autofac
的應用遠不止這些,還有一個比原來好的就是能夠實現AOP~