C# 依赖注入简介
什么是依赖注入?
依赖注入是一种设计模式,其中一个类(称为"服务")不负责创建它所依赖的对象,而是通过外部容器(如依赖注入容器)来获取这些对象。这样可以提高代码的可测试性和可维护性。
为什么需要依赖注入?
依赖注入有助于提高代码的灵活性和可测试性。例如,如果没有依赖注入,当需要更改某个依赖项时,可能需要修改很多地方。而使用依赖注入后,只需更改配置即可。
// 没有依赖注入的例子
public class OrderService
{
private readonly Logger _logger = new Logger();
public void CreateOrder()
{
_logger.Log("订单创建成功");
// 其他业务逻辑...
}
}
// 使用依赖注入的例子
public interface ILogger
{
void Log(string message);
}
public class ConsoleLogger : ILogger
{
public void Log(string message) => Console.WriteLine($"日志:{message}");
}
public class OrderService
{
private readonly ILogger _logger;
public OrderService(ILogger logger)
{
_logger = logger;
}
public void CreateOrder()
{
_logger.Log("订单创建成功");
}
}
依赖注入的三种方式
- 构造函数注入:通过类的构造函数接收依赖,是最常用的依赖注入方式。
- 属性注入:通过公共属性接收依赖,适用于可选的依赖。
- 方法注入:通过方法参数接收依赖,适用于仅在特定方法中需要的依赖。
Microsoft.Extensions.DependencyInjection
这是微软提供的一个依赖注入容器,支持多种服务生命周期(瞬时、作用域、单例)。
using Microsoft.Extensions.DependencyInjection;
public interface IUserService { }
public class UserService : IUserService { }
var services = new ServiceCollection();
services.AddTransient();
_serviceProvider = services.BuildServiceProvider();
在WPF中应用依赖注入
以下是一个简单的WPF示例,展示了如何使用依赖注入。
// 定义接口
public interface IDataService { }
public class DataService : IDataService { }
public interface ILoggerService { }
public class LoggerService : ILoggerService { }
public interface ISettingsService { }
public class SettingsService : ISettingsService { }
// 创建,注册,解析
public partial class App : Application
{
private readonly IServiceProvider _serviceProvider;
public App()
{
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
_serviceProvider = serviceCollection.BuildServiceProvider();
}
private void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<MainWindow>();
services.AddScoped();
services.AddTransient();
services.AddSingleton();
}
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var mainWindow = _serviceProvider.GetRequiredService<MainWindow>();
mainWindow.Show();
}
}
// 界面代码和后台代码省略