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

依赖注入库:实现类似Dagger/Hilt的DI框架(229)

在鸿蒙(HarmonyOS)应用开发中,随着业务复杂度的提升,模块间的依赖关系往往会变得错综复杂。引入依赖注入(DI)框架能够实现模块间的彻底解耦,提升代码的可测试性与可维护性。

针对鸿蒙生态,开发者可以选择基于注解的自动化生成方案、轻量级运行时容器,或是结合路由框架的跨模块注入方案。

一、 自动化代码生成方案:injectable + inject_generator

对于大型工程,手动维护依赖树不仅繁琐且极易出错。通过引入injectableinject_generator,开发者可以利用注解在编译期自动完成依赖组装。

  • 核心机制:利用@module@provide@injectable等注解标记依赖,通过build_runner在编译期自动扫描并生成*.inject.dart文件,构建好单例或工厂的实例化逻辑。
  • 鸿蒙适配优势:生成的代码是标准的 Dart 实例化调用,不涉及运行时反射,因此不会带来额外的性能损耗,且能在编译期提前发现依赖链条断裂或环形依赖的问题。
import { module, provide, injectable } from '@ohos/injectable'; // 1. 定义底层数据库服务模块 @module class OhosMainModule { @provide provideDb(): OhosDatabase { return new OhosDatabase(); } } // 2. 定义业务服务,声明它依赖 OhosDatabase @injectable class OhosUserService { private db: OhosDatabase; // 生成器会自动寻找并注入 OhosDatabase constructor(db: OhosDatabase) { this.db = db; } fetchUser() { console.info('通过数据库获取用户'); } }

二、 轻量级运行时 DI 容器:weaver

如果项目不需要复杂的代码生成,weaver是一个极致轻量的 DI 和服务发现框架。

  • 核心机制:提出了“注册(Register)- 注入(Inject)”模型。
  • 局部作用域隔离:支持weaver.scoped局部作用域容器,非常适合在鸿蒙多 HAP(HarmonyOS Ability Packages)模式下实现模块自治和强弱隔离。
import { weaver } from '@ohos/weaver'; // 1. 注册全局单例服务 weaver.registerSingleton<AnalyticsService>(() => new AnalyticsService()); // 2. 创建局部作用域容器(例如针对某个特定的业务模块或页面) const scopedContainer = weaver.scoped(); scopedContainer.registerFactory<PaymentService>(() => new PaymentServiceImpl()); // 3. 在业务层获取服务 const analytics = weaver.get<AnalyticsService>(); const payment = scopedContainer.get<PaymentService>();

三、 跨模块解耦方案:TheRouter 的 ServiceProvider

在鸿蒙的组件化开发中,跨模块的依赖注入是核心痛点。TheRouter框架提供了ServiceProvider能力来解决这一问题。

  • 核心机制:支持跨模块依赖注入,允许自定义注入项的创建规则与参数。
  • 单例缓存:支持注入对象缓存,多次注入只会 new 一次对象,避免内存浪费。
import { TheRouter } from '@ohos/therouter'; // 1. 在业务模块中注册服务实现 TheRouter.serviceProvider.register( 'IUserCenterService', () => new UserCenterServiceImpl(), true // true 表示开启单例缓存,多次获取只 new 一次 ); // 2. 在基础模块或任意跨模块中获取服务(无需 import 实现类) const userCenterService = TheRouter.serviceProvider.get<IUserCenterService>('IUserCenterService'); userCenterService?.login('user', 'password');

四、 避坑实践

  1. 防御循环依赖:在复杂的模块化架构中,A 依赖 B、B 又依赖 A 会导致“炸弹式堆栈溢出”。应采用延迟初始化(Lazy Fetch),在业务逻辑内部才调用df.get()weaver.get(),不要在构造函数的第一行就触发全量寻找。
  2. 异步服务预解析:鸿蒙系统中许多底层 API(如Preferences.getInstance()、设备传感器初始化)都是异步的。如果在 DI 容器就绪前就尝试获取这些服务,会导致运行时异常。可使用@preResolve注解,强制 DI 容器在初始化阶段等待异步服务完成解析。
  3. 多环境动态适配:利用@Environment('dev')@Environment('ohos_real')等环境标签,可以为同一个接口定义多份实现(例如开发环境注入内存缓存MockStorage,真机环境注入原生持久化NativeOhosStorage),实现跨环境的无缝切换。

五、 自动化代码生成实战:注解驱动与异步预解析

场景:在大型工程中,利用注解标记依赖,由生成器在编译期自动组装依赖树,并强制等待底层异步 API(如 Preferences)初始化完成,避免运行时获取空对象。

import { module, provide, injectable, preResolve, Environment } from '@ohos/injectable'; // 1. 定义鸿蒙平台模块,提供底层数据库与配置服务 @module class OhosMainModule { @provide provideDb(): OhosDatabase { return new OhosDatabase(); } // 使用 @preResolve 强制容器在初始化阶段等待异步服务完成解析 @preResolve async getPrefs(): Promise<Preferences> { return await preferences.get(getContext(this), 'app_config'); } } // 2. 定义业务服务,声明它依赖 OhosDatabase @injectable class OhosUserService { private db: OhosDatabase; constructor(db: OhosDatabase) { this.db = db; } fetchUser() { console.info('通过数据库获取用户'); } }

六、轻量级运行时 DI 容器:weaver 与局部作用域隔离

场景:在鸿蒙多 HAP(HarmonyOS Ability Packages)模式下,利用weaver实现模块自治。通过局部作用域容器(Scoped Container),避免全局单例污染,实现强弱隔离。

import { weaver } from '@ohos/weaver'; // 1. 注册全局单例服务 weaver.registerSingleton<AnalyticsService>(() => new AnalyticsService()); // 2. 创建局部作用域容器(例如针对某个特定的业务模块或页面) const scopedContainer = weaver.scoped(); scopedContainer.registerFactory<PaymentService>(() => new PaymentServiceImpl()); // 3. 在业务层获取服务 const analytics = weaver.get<AnalyticsService>(); const payment = scopedContainer.get<PaymentService>();

七、跨模块解耦实战:TheRouter 的 ServiceProvider

场景:在组件化架构中,基础模块需要调用业务模块的实现,但不能直接依赖业务模块。通过 TheRouter 的 ServiceProvider 实现跨模块接口注入与单例缓存。

import { TheRouter } from '@ohos/therouter'; // 1. 在业务模块中注册服务实现 TheRouter.serviceProvider.register( 'IUserCenterService', () => new UserCenterServiceImpl(), true // true 表示开启单例缓存,多次获取只 new 一次 ); // 2. 在基础模块或任意跨模块中获取服务(无需 import 实现类) const userCenterService = TheRouter.serviceProvider.get<IUserCenterService>('IUserCenterService'); userCenterService?.login('user', 'password');
http://www.jsqmd.com/news/1236237/

相关文章:

  • 【企业AI合规生死线】:商用部署前必须完成的4步许可证审计流程,错过第3步将触发自动终止条款
  • AI Agent 记忆策略终极指南:四种提取形式与答案质量深度分析
  • 从数据到部署:骆驼(Luotuo)项目全流程拆解与社区贡献指南
  • grunt-responsive-images在企业级项目中的应用:多环境部署与持续集成
  • Playwright CLI实战指南:让AI助手帮你搞定Web自动化测试
  • 2026上海公考培训机构多维对比 主流机构选型参考 - 资讯纵览
  • 2026重庆全屋定制深度解析:砚禾全屋定制,中高端源头工厂 - 资讯纵览
  • 南宁奢侈品回收新规落地:公安备案为硬性门槛,CCIC双检核验,交易全程可溯源 - 二奢分享官
  • 如何快速修复Windows更新故障:Reset Windows Update Tool使用指南
  • AI语音转文字准确率从68%飙升至97.3%:采访稿场景下5步精准优化法(附实测数据)
  • gh_mirrors/pi/pi-cluster集群升级与维护:安全更新与系统优化最佳实践
  • 告别繁琐命令行!Escrcpy让你像玩平板一样控制安卓手机
  • Go语言实现的GitHub客户端:gh项目架构与核心代码解析
  • 路由框架:实现页面解耦与拦截器的路由库(230)
  • 5个实战技巧:掌握slam_toolbox实现企业级2D SLAM与终身建图
  • 异地上班中专党注意:档案自持多年如何激活,不耽误考编政审 - 资讯在线
  • 字体及第三方脚本速度影响:LCP超过2.5秒?修改这2个设置立竿见影
  • Jupynium.nvim 未来路线图:即将推出的功能与改进计划
  • 【JAVA毕设源码分享】基于springboot同人创作与分享平台系统的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 如何用3D打印技术打造千元级六轴机械臂:Faze4开源项目完全指南
  • 3个必学技巧:精通Musicdl音乐下载的实战指南
  • YOLO11 RTSP流性能优化终极指南:从卡顿到流畅的完整方案
  • 深圳业主必看!装修避坑指南:5家零增项靠谱装修公司推荐 - GrowUME
  • 2026年邯郸靠谱装修公司哪家好?十大本土装修公司推荐指南 - 品牌智鉴榜
  • slam_toolbox深度技术解析:大规模环境下的终身建图与分布式SLAM架构揭秘
  • grunt-responsive-images核心功能解析:从基础尺寸设置到高级图片优化
  • 2026香港身份机构 TOP3测评:资质、通过率、性价比三维对比指南 - 资讯纵览
  • repo-automation-bots社区贡献指南:如何参与这个Google开源项目
  • AutoX:5大理由让你选择这款安卓自动化神器
  • libsm64声音播放机制:如何注册自定义音效回调函数