• 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中我们一般是把StartupConfigureServices方法返回值类型改为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的实现类OneServiceTwoService

    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去实现,当然,正常这里会有很多很多的代码~

    修改StartupProgram

    当然,需要安装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

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

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

    总结

    其实很多官方文档都讲述了,因为自己近期打算把原来的项目LJD.APP:https://github.com/jellydong/LJDAPP升级到.Net Core 3.1上,当然是一个简化版本https://github.com/jellydong/Jelly.Simple。

    所以不要怕英文,翻译插件那么好用,基本都能看懂的

    参考文档:https://autofaccn.readthedocs.io/en/latest/integration/aspnetcore.html#asp-net-core-3-0-and-generic-hosting

    当然Autofac的应用远不止这些,还有一个比原来好的就是可以实现AOP~

  • 相关阅读:
    【BZOJ2288】生日礼物 [贪心]
    Tinyhttpd阅读笔记
    数据结构-图-经典算法(三)
    数据结构-图-经典算法(二)
    数据结构-图-经典算法(一)
    TCP协议的滑动窗口协议以及流量控制
    2016腾讯实习电话面试总结---2016-03-10
    B树,B+树,B*树
    平衡二叉树(AVL树)
    二叉搜索树(二叉查找树,二叉排序树)
  • 原文地址:https://www.cnblogs.com/jellydong/p/13331450.html
Copyright © 2020-2023  润新知