当前位置: 首页 > news >正文

依赖注入

一、依赖注入的核心思想

依赖注入(Dependency Injection,DI)是一种设计模式,它的核心思想是“控制反转”(IoC),即将对象的创建和管理从应用程序代码中分离出来,交给外部容器来处理。主要概念包括:

  • 依赖:一个对象需要另一个对象来完成其工作,那么前者就依赖于后者。例如,一个orderService类可能依赖于一个ProductRepository类来获取产品信息;
  • 注入:将依赖的对象传递给需要它的对象,而不是让需要它的对象自己去创建依赖的对象。注入可以通过构造函数、属性或方法参数来实现;
  • 容器:一个管理对象创建和依赖关系的框架或库。容器负责实例化对象,解析依赖关系,并将依赖的对象注入到需要它们的对象中;

在传统的编程方式中,一个对象如果需要使用另一个对象,通常会在自身内部通过new关键字等方式直接创建被依赖的对象,这就导致了对象之间的紧密耦合。

而在IOC模式下,由IOC容器负责创建对象,并在对象需要时将其依赖的对象注入进去。这样,对象只需要关注自身的业务逻辑,而不需要关心依赖对象的创建过程,从而实现了对象之间依赖关系的解耦。

二、依赖注入的类型

1. 构造函数注入:依赖的对象通过类的构造函数传递。

public class MainViewModel
{private readonly IDataService _dataService;    public MainViewModel(IDataService dataService){_dataService = dataService;}    //使用_dataService的方法
}

2. 属性注入:依赖的对象通过类的公共属性传递。

public class MainViewModel
{public IDataService DataService{get; set;}
}

3. 方法注入:依赖的对象通过类的方法参数传递。

public class MainViewModel
{public void SettingsService(IDataService DataService){//使用DataService的方法
    }
}

三、WPF中实现依赖注入的常用方式

1. 使用Microsoft.Extensions.DependencyInjection

这是.NET Core/5+中官方推荐的DI容器(.NET Core/5+”涵盖 .NET Core 1.0-3.1 和 .NET 5/6/7/8),.NET提供了一个内置的服务容器IServiceProvider。服务通常在应用启动时注册,并追加到IServiceCollection。添加所有服务后,可以使用BuildServiceProvider创建服务容器。框架负责创建依赖关系的实例,并在不再需要时将其释放。

步骤:

  ① 首先创建一个WPF应用成,然后再Nuget包管理器中安装微软提供的依赖注入库[Microsoft.Extensions.DependencyInjection];

  ② 创建测试用的接口ITextService和实现类TextService:

namespace DemoIoc
{public interface ITextService{public string GetText();}public class TextService : ITextService{public string GetText(){return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");}}
}

 

 

  ③ 在需要调用的地方(如:MainWindow)进行ITextService接口注入:可以看出MainWindow依赖ITextService接口,而不依赖于接口的实现。这样就实现了依赖注入。

public partial class MainWindow : Window
{private ITextService textService;public MainWindow(ITextService textService){this.textService = textService;InitializeComponent();}private void Window_Loaded(object sender, RoutedEventArgs e){this.txtCurrentTime.Text = textService.GetText();}
}

  ④ 配置容器:在启动程序App.xaml.cs中,添加当前对象乘以,和服务提供对象,并在实例化服务对象的时候一次性注册,以便在后续需要的时候进行获取。

// 在App.xaml.cs 中配置服务
public partial class App : Application
{public IServiceProvider ServiceProvider{ get; private set;} //获取存放应用服务的容器protected override void OnStartup(StartupEventArgs e){
     //配置应用的服务 
var serviceCollection = new ServiceCollection();ConfigureServices(serviceCollection); ServiceProvider = serviceCollection.BuildServiceProvider();
//从依赖注入容器中获取一个`MainWindow`类型的实例。
var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();mainWindow.Show();}private void ConfigureServices(IServiceCollection services){services.AddSingleton<ITextService, TextService>();Services.AddSingleton<MainWindow>();} }

 

  • AddTransient瞬时模式:每次请求,都获取一个新的实例。使同一个请求获取多次也会是不同的实例
  • 使用方式:services.AddTransient<IOperation Transient, Operation>();
  • AddScoped:每次请求,都获取一个新的实例。同一个请求获取多次会得到相同的实例
  • 使用方式:services.AddScoped<IMyDependency, MyDependenсу>();
  • AddSingleton单例模式:每次都获取同一个实例
  • 使用方式:services.AddSingleton<IOperationSingleton, Operation>();

2. 使用依赖注入容器(如Autofac,Unity,Ninject等)

依赖注入容器是管理和创建对象及其依赖项的框架。它们可以大大简化依赖注入的实现,尤其是在大型应用中:

  • Autofac: 功能强大,性能好,支持模块化

  • Unity: 微软早期的DI容器,现在较少使用

  • Ninject: 语法简洁,适合快速开发

  • DryIoc: 高性能容器

  • Simple Injector: 强调编译时验证

① Autofac:是 .NET 生态系统中非常流行的轻量级依赖注入(DI)框架,它以高性能和灵活性著称

// 创建注册器
var builder = new ContainerBuilder();// 注册组件
builder.RegisterType<MyService>().As<IMyService>();// 构建容器
var container = builder.Build();// 从容器中解析组件
var myService = container.Resolve<IMyService>();// 使用对象
myService.DoSomething();

②  Ninject:是一个轻量级、快速的依赖注入框架,以其"超级流畅"的接口和易用性著称。

// 创建内核(容器)
IKernel kernel = new StandardKernel();// 基本绑定
kernel.Bind<IService>().To<ServiceImpl>();// 解析服务
var service = kernel.Get<IService>();// 构造函数注入示例
public class Consumer
{private readonly IService _service;public Consumer(IService service) // 自动注入
    {_service = service;}
}

DryIoc: 是另一个高性能的 .NET 依赖注入容器,以其出色的执行速度和简洁的 API 设计受到开发者青睐

// 创建容器
var container = new Container();// 注册服务
container.Register<IMessageService, EmailService>();// 解析服务
var messageService = container.Resolve<IMessageService>();// 使用服务
messageService.SendMessage("Hello, DryIoc!");

④  Unity:  是微软模式与实践团队开发的依赖注入容器,曾是微软官方推荐的DI解决方案。

// 创建容器
IUnityContainer container = new UnityContainer();// 注册类型映射
container.RegisterType<IService, ServiceImpl>();// 解析实例
IService service = container.Resolve<IService>();// 构造函数注入示例
public class Consumer
{private readonly IService _service;public Consumer(IService service) // 自动注入
    {_service = service;}
}

 

http://www.sczhlp.com/news/13303/

相关文章:

  • docker镜像的分层
  • docker端口映射
  • 昆工通信复试水?22-25年血战报告:最高1/3当场抬走
  • ️ 你的程序用了 DevExpress,别人电脑没装能运行吗?一文讲清楚!
  • python基础
  • 仿函数
  • 算法的泛化过程
  • docker容器常用命令
  • P1029 [NOIP 2001 普及组] 最大公约数和最小公倍数问题
  • docker安装(yum方式+二进制方式)
  • docker镜像常用命令
  • 8月16日随笔
  • 关于纪日法
  • electron桌面端web化方案
  • Namespace 和 Cgroups 的隔离与限制
  • docker组件、架构与运行过程
  • 短篇随笔 001
  • 2394: 洗盘子 题解
  • MediaCodec的使用
  • 基于YOLOv8的藻类细胞实时检测识别项目|完整源码数据集+PyQt5界面+完整训练流程+开箱即用!
  • Linux系统文件权限
  • excel公式中INDEX公式答疑
  • 酒店行业安全体系构建与优化策略 - 实践
  • 5分钟学会xmind思维导图
  • π0.5: a Vision-Language-Action Model with Open-World Generalization
  • 电子制造 SMT 生产线:倍福 CX 系列 PLC 与施耐德 M340 PLC 的 EtherCAT 转 DeviceNet 通讯配置案例
  • 【渲染流水线】[几何阶段]-[归一化NDC]以UnityURP为例
  • 实用指南:uni-app平板端自定义样式合集
  • Linux主机简单判断被CC攻击的网站命令-比较直接有效
  • Nginx反向代理Kafka集群