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
那咱们按照官方文档的方法修改一下。测试
效果图ui
建立完成后咱们先建立文件夹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
文件夹,在该文件夹下建立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~