天天看點

ASP.NET Core中的Ioc——Autofac

  1. ASP.NET Core中自帶的IOC容器是屬于輕量級的,功能并不是很多,隻是提供了基礎功能而已(預設采用了構造函數注入的方式,不支援屬性注入,不支援AOP),它的注入服務的生命周期有3種:
    1. AddTransient:瞬時,服務在每次請求時被建立;
    2. AddScoped:作用域,服務在每次請求時被建立,生命周期橫貫整次請求
    3. AddSingleton:單例,服務在第一次請求時被建立(或者當我們在ConfigureServices中指定建立某一執行個體并運作方法),其後的每次請求将沿用已建立服務
public void ConfigureServices(IServiceCollection services)
	    {
			services.AddTransient<ITestService1, TestService1>();//瞬時
			services.AddScoped<ITestService2, TestService2>();//作用域
			services.AddSingleton<ITestService3, TestService3>();//單例
	    }
           
  • 之後再控制器裡,用構造函數注入
public class HomeController : Controller
    {
        private readonly ITestService1 _testService1;
        private readonly ITestService2 _testService2;
        private readonly ITestService3 _testService3;

        public HomeController(ITestService1 testService1, ITestService2 testService2, ITestService3 testService3)
        {
            _testService1 = testService1;
            _testService2 = testService2;
            _testService3 = testService3;
        }
    }    
           
  1. Autofac:第三方Ioc容器Autofac的使用,支援屬性注入,支援AOP等,其步驟如下:
    1. NuGet安裝2個程式包:Autofac、Autofac.Extensions.DependencyInjection;
    2. Autofac在ASP.Net Core3.0以後,內建方式有所調整,在ASP.Net Core2中我們一般是把Startup的ConfigureServices方法傳回值類型改為IServiceProvider,會報錯:ConfigureServices returning an System.IServiceProvider isn’t supported,以下是針對ASP.Net Core3.0的修改;
    3. 修改

      Program

      ,增加

      UseServiceProviderFactory(new AutofacServiceProviderFactory())

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>();
                });
    }
           
  1. 注冊服務,修改

    Startup

public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(o => o.EnableEndpointRouting = false);
			//注冊服務(注冊依賴)
          	services.AddTransient<Interface1, TestService1>();//瞬時
            services.AddSingleton<Interface2, TestService2>();//單例
            services.AddScoped<Interface3, TestService3>();//作用域
        }    
           

第4步,注冊服務,還有另一種處理方式,即把注冊服務獨立出來:

//注冊服務獨立出來,新增一個類,繼承 Autofac.Module
    public class CustomAutofacModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
        	//注冊服務
            builder.RegisterType(typeof(Service1)).As<Interface1>().SingleInstance();//單例
            builder.RegisterType(typeof(Service2)).As<Interface2>().InstancePerLifetimeScope();//線程獨立
            builder.RegisterType(typeof(Service3)).As<Interface3>().InstancePerDependency();//瞬時,為每個依賴或者調用(Resolve())都建立一個新的對象
        }
    }
           

Startup

裡就不用注冊服務了,在

ConfigureServices

下面,新增一個

ConfigureContainer

方法

// 注冊服務獨立出來
        public void ConfigureContainer(ContainerBuilder builder)
        {
            builder.RegisterModule(new CustomAutofacModule());
        }
           
  1. 以上Autofac配置完成了,最後在控制器裡調用,利用控制器的構造函數注入
public class HomeController : Controller
    {
        private readonly Interface1 _Service1;
        private readonly Interface2 _Service2;
        private readonly Interface3 _Service3;

        public HomeController(Interface1 s1, Interface2 s2, Interface3 s3)
        {
            //依賴注入
            _Service1 = s1;
            _Service2 = s2;
            _Service3 = s3;
        }
        public IActionResult Index()
        {
            _Service1.Show();
            _Service2.Show();
            _Service3.Show();

            return View();
        }
    }
           

6.補充說明,可以使用批量注冊方法:

ASP.NET Core中的Ioc——Autofac
//批量注冊
    public class AutofacModule : Autofac.Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            string basePath = AppContext.BaseDirectory;
            var assembly = Assembly.LoadFrom(Path.Combine(basePath, "AspNetCore.Service.dll"));
            builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces();
        }
    }
           
  1. 補充說明:
    1. builder.RegisterType<A>().AsImplementedInterfaces();

      ,以接口方式進行注入,使用時用IA,會傳回一個A的執行個體,即将自身的執行個體進行注入;
    2. builder.RegisterType<A>().AsImplementedInterfaces().InstancePerRequest() ;

      每次請求共享同一個執行個體,使用ef時,使不同的操作使用同一個資料上下文;
    3. builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())

      注冊了目前程式集内的所有的類;
    4. InstancePerHttpRequest

      在一次Http請求上下文中,共享一個元件執行個體。僅适用于asp.net mvc開發

參考文檔:ASP.NET Core依賴注入&AutoFac

Autofac在ASP.Net Core3.0配置

.net core2.1 三層中使用Autofac代替原來Ioc

關于依賴注入autofac的相關知識