我們在使用AddScoped、AddTransient、AddSingleton這類方法的時候很是麻煩。我們每增加一個介面以及其實現的時候,是不是需要在這裡硬編碼註冊一行代碼呢?項目小還好,但當我們的項目變得龐大之後,這裡的依賴註入怎麼來維護呢?在網上翻了半天,看了很多方法,其代碼的實現個人感覺都不 ...
我們在使用AddScoped、AddTransient、AddSingleton這類方法的時候很是麻煩。我們每增加一個介面以及其實現的時候,是不是需要在這裡硬編碼註冊一行代碼呢?項目小還好,但當我們的項目變得龐大之後,這裡的依賴註入怎麼來維護呢?
在網上翻了半天,看了很多方法,其代碼的實現個人感覺都不是太優雅,想想還是自己寫一個比較實用吧,我們只需按照一個規定來定義和實現介面。應用程式就能自動掃描並註冊這些程式集中的介面和對應實現類,完成依賴註入的自動註冊,具體的實現可以通過介面或特性來實現,如果需要區分AddScoped、AddTransient、AddSingleton可以通過定義不同的介面去實現,這裡我們定義IDenpendency介面做演示,具體實現如下:
第一步:創建如下這樣一個空介面
public interface IDenpendency { }
第二步:創建需要註入的功能介面,這類介面就是你想實現某些功能的封裝,它們都繼承第一步創建的介面IDenpendency,如下,我創建一個功能介面
public interface IUserService:IDenpendency
{
//function
}
第三步:實現需要註入的功能介面,如下,我創建了一個實現UserService的類
public class UserService:IUserService
{
//function的具體實現
}
第四步:擴展IServiceCollection批量註入方法AddDataService
public static class DataServiceExtension { /// <summary> /// 註入數據 /// </summary> /// <param name="services"></param> public static IServiceCollection AddDataService(this IServiceCollection services) { #region 依賴註入 //services.AddScoped<IUserService, UserService>(); var baseType = typeof(IDependency); var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; var referencedAssemblies = System.IO.Directory.GetFiles(path, "*.dll").Select(Assembly.LoadFrom).ToArray(); var types = referencedAssemblies .SelectMany(a => a.DefinedTypes) .Select(type => type.AsType()) .Where(x => x != baseType && baseType.IsAssignableFrom(x)).ToArray(); var implementTypes = types.Where(x => x.IsClass).ToArray(); var interfaceTypes = types.Where(x => x.IsInterface).ToArray(); foreach (var implementType in implementTypes) { var interfaceType = interfaceTypes.FirstOrDefault(x => x.IsAssignableFrom(implementType)); if (interfaceType != null) services.AddScoped(interfaceType, implementType); } #endregion return services; } }View Code
第五步:在Startup.cs調用AddDataService方法進行批量註入
本人原創文章,非商業用途可隨意轉載,轉載請保留原文出處