一. 再探依賴注入
其它詳細用法參考之前的博客:https://www.cnblogs.com/yaopengfei/p/10754397.html
https://www.cnblogs.com/yaopengfei/p/12664400.html
官網:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-6.0
1. coreMvc中注入
直接在Program中注入即可, 可以以接口的形式注入,也可以直接注入類
//1. 普通注入
builder.Services.AddScoped<IUserInfo, UserInfo>();
builder.Services.AddScoped<RoleInfo>();
使用的時候在控制器中通過構造函數注入即可,代碼略。
2. 在應用啓動中解析
(即在program中要使用,這裏是解析使用,註冊使用的還是1中的註冊)
(1). 通過 var serviceScope = app.Services.CreateScope()
(2). 通過GetRequiredService方法進行對象的解析
var app = builder.Build();
//2.在應用啓動中解析使用(使用的還是1中的普通注入)
using (var serviceScope = app.Services.CreateScope())
{
var services = serviceScope.ServiceProvider;
var userInfo = services.GetRequiredService<IUserInfo>();
var roleInfo = services.GetRequiredService<RoleInfo>();
Console.WriteLine("------------------測試在應用啓動中解析使用------------------------------");
Console.WriteLine(userInfo.GetInfo());
Console.WriteLine(roleInfo.GetInfo());
}
3.直接在控制檯中使用
直接註冊+解析
需要依賴【 Microsoft.Extensions.DependencyInjection】程序集,詳見下面代碼
//3. 測試控制檯中使用
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton<IUserInfo, UserInfo>();
var serviceProvider = serviceCollection.BuildServiceProvider();
IUserInfo userService = serviceProvider.GetRequiredService<IUserInfo>();
//下面是使用
var result = userService.GetInfo();
}
二. 多項目框架集成
1. 需求
有多個項目, Ypf.Service、Ypf.IService、03-CoreMvcDI三個項目, 其中CoreMvcDI添加對Ypf.Service的引用,然後把Ypf.Service項目的輸出路徑改爲 【..\03-CoreMvcDI\bin\】
想把Ypf.Service中所有實現ISupport接口的類註冊個他的實現接口
[FromServices] IInfo2 _info2 是註冊失敗的,因爲沒有實現ISupport接口 (需要加上以後再測試一下哦)
特別注意:這裏的輸出路徑改爲 Ypf.Service項目的輸出路徑改爲 【..\03-CoreMvcDI\bin\】,利用合併文件夾的原則實現!!! 因爲Ypf.Service項目也會生成一個Debuger文件夾
2. 原生反射寫法
(和之前Core5.0中的寫法基本一致)
(1). 拼接dll的路徑,通過反射進行加載
(2). 獲取該dll中的符合條件的類(A.去掉抽象類 B.該類要實現ISupport接口)
(3). 遍歷類
A. 拿到該類的所有接口(去掉ISupport接口)
B. 遍歷接口,把該類註冊給所有實現的接口
代碼分享:
{
var dirName = "03-Ypf.Service.dll";
Assembly asmService = Assembly.LoadFile(AppContext.BaseDirectory + dirName);
//抽象類不進行注入,沒有實現ISupport接口的類不進行注入
var classList = asmService.GetTypes().Where(t => !t.GetTypeInfo().IsAbstract && typeof(ISupport).IsAssignableFrom(t)).ToList();
foreach (Type serviceType in classList)
{
//把一個類註冊給它實現的全部接口(除了ISupport接口外)
var interfaceTypes = serviceType.GetInterfaces().Where(t => t.Name != "ISupport").ToList();
foreach (var interfaceType in interfaceTypes)
{
builder.Services.AddScoped(interfaceType, serviceType);
}
}
}
3. AutoFac集成新寫法
和之前Core5.0的寫法有區別,詳見Program中的代碼
public class MyAutoFacModule : Module
{
protected override void Load(ContainerBuilder builder)
{
{
//這裏就是AutoFac的注入方式,下面採用常規的方式
//詳見:https://www.cnblogs.com/yaopengfei/p/9479268.html
//官網:https://autofac.org/
//特別注意:其中很大的一個變化在於,Autofac 原來的一個生命週期InstancePerRequest,將不再有效。正如我們前面所說的,整個request的生命週期被ASP.NET Core管理了,
//所以Autofac的這個將不再有效。我們可以使用 InstancePerLifetimeScope ,同樣是有用的,對應了我們ASP.NET Core DI 裏面的Scoped。
//在普通類中配置文件的讀取麻煩,後面封裝(注:appsettings.json要改爲始終複製)
var Configuration = new ConfigurationBuilder().AddJsonFile(AppContext.BaseDirectory + "appsettings.json").Build();
var dirName = Configuration["IocDll"];
Assembly asmService = Assembly.LoadFile(AppContext.BaseDirectory + dirName);
builder.RegisterAssemblyTypes(asmService)
.Where(t => !t.IsAbstract && typeof(ISupport).IsAssignableFrom(t)) //只有實現了ISupport接口的類才進行註冊
.AsImplementedInterfaces() //把一個類註冊給它實現的全部接口
.InstancePerLifetimeScope() //作用域單例(比如Task.Run就是另外一個作用域),而非請求內單例(請求內單例用:InstancePerRequest)
.PropertiesAutowired(); //在core裏表示在注入類中實現構造函數注入
}
}
}
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
// Register services directly with Autofac here. Don't call builder.Populate(), that happens in AutofacServiceProviderFactory.
builder.Host.ConfigureContainer<ContainerBuilder>(builder => builder.RegisterModule(new MyAutoFacModule()));
三. 老楊的開源框架
https://github.com/yangzhongke/NETBookMaterials/tree/main/%E6%9C%80%E5%90%8E%E5%A4%A7%E9%A1%B9%E7%9B%AE%E4%BB%A3%E7%A0%81/YouZack-VNext/Zack.Commons
主要分析RunModuleInitializers方法和ReflectionHelper.cs
!
- 作 者 : Yaopengfei(姚鵬飛)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 聲 明1 : 如有錯誤,歡迎討論,請勿謾罵^_^。
- 聲 明2 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。