ASP.Net Core 3.1 With Autofac ConfigureServices returning an System.IServiceProvider isn't supported
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
。我们可以先看一下部分代码:
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/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
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
1、增加属性
AutofacContainer
2、增加方法
ConfigureContainer
它在ConfigureServices
之后运行3、给属性赋值(可选)
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
运行,断点看下结果是否正确
修改下实现类,也是正确的~
总结
本文来自博客园,作者:太太怕我,转载请注明原文链接:https://www.cnblogs.com/Andy-Blog/p/16389590.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现