有時候我們在服務注冊的時候會遇到這樣一個場景,我們的同一個接口,有著多個實現,且我們還要同時使用這些實現的時候,這個時候該怎么辦?我們可以使用鍵控服務依賴注入
鍵控服務依賴注入(Keyed Dependency Injection) 是 .NET 8 引入的新特性,允許你使用鍵(Key) 來區分同一接口的多個實現,它允許你注冊接口的多個實現,每個實現都與一個唯一鍵相關聯,然后基于該鍵解析所需的實現。
實現
鍵控服務依賴注入的方式很簡單,下面我將從一個例子來說說如何實現
例:我們有一個存儲數據的服務,我們既需要存在文件中也需要存在數據庫中,這時候我們就會有兩個服務的實現
基礎類
public interface IDataService
{void SaveData(string data);
}public class LocalDataStorage : IDataService
{public void SaveData(string data){Console.WriteLine("方法1: " + data);}
}public class FileDataStorage : IDataService
{public void SaveData(string data){Console.WriteLine("方法2: " + data);}
}
注冊
我們通過名稱為不同的實現傳入了名稱
builder.Services.AddKeyedSingleton<IDataService, LocalDataStorage >("Fun1");
builder.Services.AddKeyedSingleton<IDataService, FileDataStorage >("Fun2");
解析服務
1.構造函數獲取
我們可以在構造函數中進行注入,在這里我們需要用到[FromKeyedServices(“名稱”))
特性來標記需要獲取哪個實現。
public class DataController : ControllerBase
{private readonly IDataService dbService;private readonly IDataService fileService;public DataController([FromKeyedServices("Fun1")] IDataService dbService,[FromKeyedServices("Fun2")] IDataService fileService){dbService= dbService;fileService= fileService;}
}
在例子中我們在構造函數中注入了兩種實現。
2.通過 IServiceProvider 手動解析
public class MyService
{private readonly IDataService _dbService;public MyService(IServiceProvider serviceProvider){_dbService = serviceProvider.GetRequiredKeyedService<IDataService>("Fun1");}
}
建議
我們在使用鍵控服務依賴注入時,我們盡量不使用字符串這種硬編碼作為KEY名稱,建議使用nameof或者枚舉作為KEY值進行服務的解析
優勢
NET 8鍵控服務依賴項注入功能彌補了之前版本接口不能多個實現的缺陷。鍵控服務依賴項注入提供了一種強大的機制來管理和解析接口的多個實現。它允許開發人員根據提供的密鑰選擇特定的實現,從而實現更靈活、更高效的應用程序設計。
往期推薦
大家如何需要了解依賴注入更詳細的內容,可以閱讀我之前的文章
.NET依賴注入IOC你了解嗎?