ASP.Net Core 3.1 With Autofac ConfigureServices returning an System.IServiceProvider isn't suppor...

ASP.Net Core 3.1 With Autofac ConfigureServices returning an System.IServiceProvider isn't supported.html

前言

Autofac在ASP.Net Core3.0之後,集成方式有所調整。在ASP.Net Core2中咱們通常是把StartupConfigureServices方法返回值類型改成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的實現類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

一、增長屬性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。

因此不要怕英文,翻譯插件那麼好用,基本都能看懂的

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

固然Autofac的應用遠不止這些,還有一個比原來好的就是能夠實現AOP~

相關文章
相關標籤/搜索