C#中的依賴注入Dependency Injection DI的實(shí)現(xiàn)步驟
在C#中,依賴注入(Dependency Injection, DI)是一種實(shí)現(xiàn)控制反轉(zhuǎn)(IoC)的設(shè)計(jì)模式,用于解耦組件依賴關(guān)系。以下是基于 .NET Core/ .NET 5+ 的依賴注入配置詳細(xì)步驟和用法:
1. 基本概念
- 服務(wù)(Service):被注入的依賴項(xiàng)(如接口、類)。
- 容器(Container):管理服務(wù)的創(chuàng)建和生命周期(如
IServiceCollection)。 - 生命周期:
- Transient:每次請求創(chuàng)建新實(shí)例。
- Scoped:同一作用域內(nèi)共享實(shí)例(如一次HTTP請求)。
- Singleton:全局單例。
2. 配置依賴注入的步驟
步驟1:定義服務(wù)接口和實(shí)現(xiàn)類
// 定義接口
public interface IMyService
{
string GetMessage();
}
// 實(shí)現(xiàn)接口
public class MyService : IMyService
{
public string GetMessage() => "Hello from MyService!";
}步驟2:注冊服務(wù)到容器
在 Program.cs 或 Startup.cs(.NET 6+ 通常使用 Program.cs):
var builder = WebApplication.CreateBuilder(args); // 注冊服務(wù)(生命周期可選) builder.Services.AddTransient<IMyService, MyService>(); // 瞬時 builder.Services.AddScoped<IMyService, MyService>(); // 作用域 builder.Services.AddSingleton<IMyService, MyService>(); // 單例 // 直接注冊類(無接口) builder.Services.AddTransient<MyService>();
步驟3:注入服務(wù)到目標(biāo)類
通過構(gòu)造函數(shù)注入:
public class MyController : ControllerBase
{
private readonly IMyService _service;
// 構(gòu)造函數(shù)自動注入
public MyController(IMyService service)
{
_service = service;
}
[HttpGet]
public IActionResult Get()
{
return Ok(_service.GetMessage());
}
}3. 在非Web應(yīng)用(如WPF/控制臺)中使用DI
WPF 示例
安裝NuGet包:
Install-Package Microsoft.Extensions.DependencyInjection
配置DI容器(在 App.xaml.cs):
public partial class App : Application
{
public IServiceProvider ServiceProvider { get; private set; }
protected override void OnStartup(StartupEventArgs e)
{
var services = new ServiceCollection();
// 注冊服務(wù)
services.AddTransient<IMyService, MyService>();
services.AddSingleton<MainWindow>(); // 注冊主窗口
ServiceProvider = services.BuildServiceProvider();
// 解析主窗口并顯示
var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
mainWindow.Show();
}
}在窗口/ViewModel中注入:
public partial class MainWindow : Window
{
public MainWindow(IMyService service)
{
InitializeComponent();
var message = service.GetMessage(); // 使用注入的服務(wù)
}
}4. 高級用法
4.1 注入多個實(shí)現(xiàn)(命名或策略模式)
// 注冊多個實(shí)現(xiàn)
builder.Services.AddTransient<IMyService, ServiceA>();
builder.Services.AddTransient<IMyService, ServiceB>();
// 通過 IEnumerable<T> 獲取所有實(shí)現(xiàn)
public class Consumer
{
public Consumer(IEnumerable<IMyService> services)
{
foreach (var service in services)
{
service.DoSomething();
}
}
}4.2 使用工廠模式動態(tài)創(chuàng)建服務(wù)
builder.Services.AddTransient<IMyService>(provider =>
{
var config = provider.GetRequiredService<IConfiguration>();
return new MyService(config.GetValue<string>("Mode"));
});4.3 生命周期管理注意事項(xiàng)
- 避免Singleton依賴Scoped服務(wù):可能導(dǎo)致Captive Dependency問題。
- IDisposable處理:容器會自動釋放實(shí)現(xiàn)了
IDisposable的服務(wù)。
5. 常見問題解決
錯誤:未注冊服務(wù)
System.InvalidOperationException: No service for type 'IMyService' has been registered.
解決:檢查服務(wù)是否在 IServiceCollection 中正確注冊。
循環(huán)依賴
重構(gòu)代碼以避免構(gòu)造函數(shù)循環(huán)引用,或用 Lazy<T> 延遲初始化。
6. 總結(jié)表格
| 操作 | 代碼示例 | 說明 |
|---|---|---|
| 注冊Transient服務(wù) | services.AddTransient<IMyService, MyService>(); | 每次請求新實(shí)例 |
| 注冊Scoped服務(wù) | services.AddScoped<IMyService, MyService>(); | 同一作用域內(nèi)共享實(shí)例 |
| 注冊Singleton服務(wù) | services.AddSingleton<IMyService, MyService>(); | 全局單例 |
| 構(gòu)造函數(shù)注入 | public MyClass(IMyService service) | 自動解析依賴 |
| 手動解析服務(wù) | var service = provider.GetRequiredService<IMyService>(); | 從容器獲取實(shí)例 |
通過以上步驟,可以靈活地在C#項(xiàng)目中配置和使用依賴注入,提升代碼的可測試性和可維護(hù)性。
到此這篇關(guān)于C#中的依賴注入Dependency Injection DI的實(shí)現(xiàn)步驟的文章就介紹到這了,更多相關(guān)C# 依賴注入內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Unity接入高德開放API實(shí)現(xiàn)IP定位
這篇文章主要為大家介紹了Unity如何接入高德開放API實(shí)現(xiàn)IP定位功能,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定參考價(jià)值,需要的可以參考一下2022-04-04
C# 批量生成隨機(jī)密碼必須包含數(shù)字和字母并用加密算法加密
這篇文章主要介紹了C# 批量生成隨機(jī)密碼必須包含數(shù)字和字母并用加密算法加密,需要的朋友參考下2017-01-01
C#實(shí)現(xiàn)拷貝文件的9種方法小結(jié)
最近遇一個問題,一個程序調(diào)用另一個程序的文件,結(jié)果另一個程序的文件被占用,使用不了文件,這時候的解決方案就是把另一個程序的文件拷貝到當(dāng)前程序就可以了,本文介紹用C#拷貝文件的多種方式,需要的朋友可以參考下2024-04-04
C# 文件操作函數(shù) 創(chuàng)建文件 判斷存在
本文列舉了C#中文件操作中常用的函數(shù),創(chuàng)建文件和判斷文件存不存在的基本使用,簡單實(shí)用,希望能幫到大家。2016-05-05
C#向數(shù)據(jù)庫中插入或更新null空值與延遲加載lazy
這篇文章介紹了C#向數(shù)據(jù)庫中插入或更新null空值與延遲加載lazy,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05

