.net core 3.1 使用autofac注入
在ASP.NET Core中,自帶的IOC容器相關的使用方式和注入類型的生命周期.
微軟給自行注入的服務,提供了3種生命周期.
Transient(瞬時的)
每次請求時都會創建的瞬時生命周期服務。這個生命周期最適合輕量級,無狀態的服務。
Scoped(作用域的)
在同作用域,服務每個請求只創建一次。
Singleton(唯一的)
全局只創建一次,第一次被請求的時候被創建,然后就一直使用這一個.
如何使用這三種生命周期呢?.我們直接在注入的時候用不同的方法就行了,代碼如下:
1
2
3
|
services.AddTransient<ITestService, TestService>();
services.AddScoped<ITestService2, TestService2>();
services.AddSingleton<ITestService3, TestService3>();
|
自帶的IOC 做一些小的項目完全沒有問題,但是大項目使用起來就比較單一,所以我們將默認的IOC容器替換為Autofac
.net core 2.x和3.x 使用autofac注入方式不一樣,此文章是針對.net core 3.x
首先,我們需要從nuget引用相關的包.
Autofac.Extensions.DependencyInjection(這個包擴展了一些微軟提供服務的類.來方便替換autofac)
然后在Program.cs 新增一行代碼
1
2
3
4
5
6
|
public
static
IHostBuilder CreateHostBuilder(
string
[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
}).UseServiceProviderFactory(
new
AutofacServiceProviderFactory());
|
然后在Startup.cs 增加方法
1
2
3
4
|
public
void
ConfigureContainer(ContainerBuilder containerBuilder)
{
containerBuilder.RegisterModule<ConfigureAutofac>();
}
|
1
|
ConfigureAutofac 是自己封裝的一個類 繼承了 Autofac.Module 也可以將以下代碼直接寫在這個方法里面:
|
public class ConfigureAutofac : Autofac.Module { protected override void Load(ContainerBuilder containerBuilder) { //直接注冊某一個類和接口 //左邊的是實現類,右邊的As是接口 //containerBuilder.RegisterType<TestServiceE>().As<ITestServiceE>().SingleInstance(); #region 方法1 Load 適用於無接口注入 //var assemblysServices = Assembly.Load("Exercise.Services"); //containerBuilder.RegisterAssemblyTypes(assemblysServices) // .AsImplementedInterfaces() // .InstancePerLifetimeScope(); //var assemblysRepository = Assembly.Load("Exercise.Repository"); //containerBuilder.RegisterAssemblyTypes(assemblysRepository) // .AsImplementedInterfaces() // .InstancePerLifetimeScope(); #endregion #region 方法2 選擇性注入 與方法1 一樣 // Assembly Repository = Assembly.Load("Exercise.Repository"); // Assembly IRepository = Assembly.Load("Exercise.IRepository"); // containerBuilder.RegisterAssemblyTypes(Repository, IRepository) //.Where(t => t.Name.EndsWith("Repository")) //.AsImplementedInterfaces().PropertiesAutowired(); // Assembly service = Assembly.Load("Exercise.Services"); // Assembly Iservice = Assembly.Load("Exercise.IServices"); // containerBuilder.RegisterAssemblyTypes(service, Iservice) //.Where(t => t.Name.EndsWith("Service")) //.AsImplementedInterfaces().PropertiesAutowired(); #endregion #region 方法3 使用 LoadFile 加載服務層的程序集 將程序集生成到bin目錄 實現解耦 不需要引用 //獲取項目路徑 var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath; var ServicesDllFile = Path.Combine(basePath, "Exercise.Services.dll");//獲取注入項目絕對路徑 var assemblysServices = Assembly.LoadFile(ServicesDllFile);//直接采用加載文件的方法 containerBuilder.RegisterAssemblyTypes(assemblysServices).AsImplementedInterfaces(); var RepositoryDllFile = Path.Combine(basePath, "Exercise.Repository.dll"); var RepositoryServices = Assembly.LoadFile(RepositoryDllFile);//直接采用加載文件的方法 containerBuilder.RegisterAssemblyTypes(RepositoryServices).AsImplementedInterfaces(); #endregion #region 在控制器中使用屬性依賴注入,其中注入屬性必須標注為public //在控制器中使用屬性依賴注入,其中注入屬性必須標注為public var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes() .Where(type => typeof(Microsoft.AspNetCore.Mvc.ControllerBase).IsAssignableFrom(type)).ToArray(); containerBuilder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired(); #endregion } }
注:業務邏輯層每個類都以Service結尾 如下截圖:
然后控制器通過構造函數注入,或者屬性注入測試 如下:
藍色框為屬性注入 發現為Null 需要在Startup.cs 的 ConfigureServices 方法下加入如下代碼
1
|
services.AddControllers().AddControllersAsServices();
//控制器當做實例創建
|
看到好的博文記錄一下:
https://www.cnblogs.com/diwu0510/p/11562248.html
AutoFac中的方法說明: