鸿蒙Flutter 依赖注入模式:使用Provider管理服务类 一、依赖注入概述依赖注入Dependency Injection简称DI是一种软件设计模式用于实现控制反转Inversion of Control简称IoC。在Flutter开发中依赖注入可以帮助我们解耦组件组件不直接创建依赖降低耦合度提高可测试性方便替换为mock对象进行测试简化维护集中管理依赖易于维护和替换实现复用同一个服务可以在多个组件中复用Provider不仅可以用于状态管理还可以作为依赖注入容器管理服务类的生命周期。二、创建服务类在使用Provider进行依赖注入之前我们需要先创建服务类。服务类通常是无状态的工具类提供特定的功能。2.1 日志服务classLogService{voidinfo(Stringmessage){debugPrint([INFO]$message);}voiderror(Stringmessage,[Object?error]){debugPrint([ERROR]$message:$error);}}2.2 存储服务classStorageService{String_data;FuturevoidsaveData(Stringdata)async{awaitFuture.delayed(constDuration(milliseconds:100));_datadata;}FutureStringloadData()async{awaitFuture.delayed(constDuration(milliseconds:100));return_data;}}2.3 API服务classApiService{FutureMapString,dynamicfetchProduct(Stringid)async{awaitFuture.delayed(constDuration(seconds:1));return{id:id,name:商品$id,price:99.9,};}}三、使用Provider注入服务使用Provider注入服务非常简单只需要在MultiProvider中声明即可MultiProvider(providers:[ProviderLogService(create:(_)LogService()),ProviderStorageService(create:(_)StorageService()),ProviderApiService(create:(_)ApiService()),ChangeNotifierProvider(create:(context)DataProvider(logService:context.readLogService(),storageService:context.readStorageService(),),),],child:constMyApp(),)3.1 注入不可变服务对于无状态的服务类使用Provider即可ProviderLogService(create:(_)LogService())3.2 注入可变状态对于需要管理状态的类使用ChangeNotifierProviderChangeNotifierProvider(create:(context)DataProvider(logService:context.readLogService(),storageService:context.readStorageService(),),)四、在Provider中使用依赖在ChangeNotifier中使用依赖注入的服务classDataProviderextendsChangeNotifier{finalLogService_logService;finalStorageService_storageService;String_data初始数据;DataProvider({requiredLogServicelogService,requiredStorageServicestorageService,}):_logServicelogService,_storageServicestorageService;Stringgetdata_data;FuturevoidupdateData(StringnewData)async{_logService.info(更新数据:$newData);_datanewData;await_storageService.saveData(newData);notifyListeners();}FuturevoidloadData()async{_logService.info(加载数据);_dataawait_storageService.loadData();notifyListeners();}}五、在Widget中使用服务在Widget中使用依赖注入的服务5.1 获取服务classProductDetailPageextendsStatelessWidget{constProductDetailPage({super.key});overrideWidgetbuild(BuildContextcontext){finallogServicecontext.readLogService();returnScaffold(appBar:AppBar(title:constText(商品详情)),body:Center(child:ElevatedButton(onPressed:(){logService.info(用户点击加入购物车);context.readCartProvider().addItem(1,商品,19.9);},child:constText(加入购物车),),),);}}5.2 注意事项使用context.readT()获取不需要监听的服务使用context.watchT()获取需要监听变化的状态服务必须在当前Provider之前声明依赖注入的服务默认是单例六、单例服务与工厂模式6.1 Provider默认创建单例Provider默认创建单例实例整个应用中只创建一次MultiProvider(providers:[Provider(create:(_)ApiService()),],child:constMyApp(),)6.2 使用Provider.value如果需要传入已存在的实例可以使用Provider.valuefinalapiServiceApiService();MultiProvider(providers:[Provider.value(value:apiService),],child:constMyApp(),)6.3 延迟初始化使用ProxyProvider进行延迟初始化只有在需要时才创建ProviderMultiProvider(providers:[Provider(create:(_)ApiService()),ChangeNotifierProxyProviderApiService,CartProvider(create:(context)CartProvider(apiService:context.read()),update:(context,apiService,cartProvider){returncartProvider!..updateApiService(apiService);},),],child:constMyApp(),)七、依赖注入的优势优势说明解耦组件不直接创建依赖降低耦合可测试方便替换为mock对象进行测试可维护集中管理依赖易于维护可复用同一个服务可以在多个组件中复用生命周期管理Provider自动管理服务生命周期八、最佳实践8.1 将服务类与状态类分离服务类应该是无状态的工具类状态类应该只负责管理状态// 服务类 - 无状态classApiService{FutureUserfetchUser(Stringid)async{...}}// 状态类 - 管理状态classUserProviderextendsChangeNotifier{finalApiService_apiService;User?_user;UserProvider({requiredApiServiceapiService}):_apiServiceapiService;}8.2 使用Provider注入不可变服务对于无状态的服务使用Provider而不是ChangeNotifierProviderProviderLogService(create:(_)LogService())8.3 使用ChangeNotifierProvider管理可变状态对于需要管理状态的类使用ChangeNotifierProviderChangeNotifierProvider(create:(_)CartProvider())8.4 按依赖顺序声明Provider依赖其他Provider的Provider必须在被依赖的Provider之后声明MultiProvider(providers:[ProviderApiService(create:(_)ApiService()),// CartProvider依赖ApiService必须在ApiService之后ChangeNotifierProvider(create:(context)CartProvider(apiService:context.read()),),],child:constMyApp(),)8.5 在构造函数中注入依赖不要在方法中直接使用context.read而是在构造函数中注入依赖classCartProviderextendsChangeNotifier{finalApiService_apiService;// 正确在构造函数中注入CartProvider({requiredApiServiceapiService}):_apiServiceapiService;voidfetchProducts(){// 使用注入的依赖_apiService.fetchProducts();}}九、代码示例9.1 创建一个依赖注入演示页面classDependencyInjectionPageextendsStatelessWidget{constDependencyInjectionPage({super.key});overrideWidgetbuild(BuildContextcontext){returnMultiProvider(providers:[ProviderLogService(create:(_)LogService()),ProviderStorageService(create:(_)StorageService()),ChangeNotifierProvider(create:(context)DataProvider(logService:context.readLogService(),storageService:context.readStorageService(),),),],child:Scaffold(appBar:AppBar(title:constText(依赖注入模式演示)),body:ListView(padding:constEdgeInsets.all(16),children:[_buildSection(服务类定义,_serviceDefinition()),_buildSection(依赖注入演示,_diDemo()),_buildSection(在Provider中使用依赖,_providerWithDependencies()),_buildSection(依赖注入优势,_diAdvantages()),],),),);}Widget_buildSection(Stringtitle,Widgetcontent){returnCard(margin:constEdgeInsets.only(bottom:16),child:Padding(padding:constEdgeInsets.all(16),child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text(title,style:constTextStyle(fontSize:18,fontWeight:FontWeight.bold)),constSizedBox(height:12),content,],),),);}Widget_diDemo(){returnColumn(children:[ConsumerDataProvider(builder:(context,provider,child){returnText(当前数据:${provider.data},style:constTextStyle(fontSize:18),);},),constSizedBox(height:16),TextField(decoration:constInputDecoration(labelText:输入新数据),onSubmitted:(value){context.readDataProvider().updateData(value);},),constSizedBox(height:16),ElevatedButton(onPressed:()context.readDataProvider().updateData(Hello DI!),child:constText(设置Hello),),],);}}9.2 代码解析在这个演示页面中服务类定义展示了LogService、StorageService等服务类的定义方式依赖注入演示展示了如何使用MultiProvider注入多个服务在Provider中使用依赖展示了如何在DataProvider中使用注入的服务依赖注入优势总结了依赖注入的优势十、关键要点10.1 Provider可作为依赖注入容器使用Provider不仅可以管理状态还可以管理服务类的生命周期。10.2 使用Provider注入不可变服务对于无状态的服务类使用Provider即可不需要使用ChangeNotifierProvider。10.3 Provider默认创建单例实例Provider默认创建单例实例整个应用中只创建一次。10.4 服务之间可以有依赖关系一个Provider可以依赖其他Provider但必须按依赖顺序声明。10.5 便于测试和维护使用依赖注入可以方便地替换为mock对象进行测试同时也便于维护和扩展。十一、总结依赖注入是一种重要的软件设计模式可以帮助我们解耦组件、提高可测试性和可维护性。在Flutter中Provider不仅可以用于状态管理还可以作为依赖注入容器使用。在实际开发中建议遵循以下原则将服务类与状态类分离使用Provider注入不可变服务使用ChangeNotifierProvider管理可变状态按依赖顺序声明Provider在构造函数中注入依赖不要直接使用context.read希望本文能帮助你掌握依赖注入模式的使用并在实际项目中正确应用

相关新闻

相关新闻

企业招聘管理系统JAVA源代码+数据库,实现公司职位发布,简历投递,招聘管理,开箱就能用的项目-BOSS直聘源码

企业招聘管理系统JAVA源代码+数据库,实现公司职位发布,简历投递,招聘管理,开箱就能用的项目-BOSS直聘源码

博主介绍: 所有项目都配有从入门到精通的安装教程,可二开,提供核心代码讲解,项目指导。 项目配有对应开发文档、解析等 项目都录了发布和功能操作演示视频;项目的界面和功能都可以定制,包安装运行&#xff…

2026/7/20 19:39:47
【小程序课程设计/毕业设计】校园专业信息聚合与科普小程序的设计与实现 智慧校园专业报考解读服务管理系统【附源码、数据库、万字文档】

【小程序课程设计/毕业设计】校园专业信息聚合与科普小程序的设计与实现 智慧校园专业报考解读服务管理系统【附源码、数据库、万字文档】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/20 19:39:47
小程序毕设项目:基于小程序的个性化健康生活指导平台 居民健康生活习惯监督与管理小程序 轻量化智慧健康生活服务管理系统 (源码+文档,讲解、调试运行,定制等)

小程序毕设项目:基于小程序的个性化健康生活指导平台 居民健康生活习惯监督与管理小程序 轻量化智慧健康生活服务管理系统 (源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/20 19:39:47

最新新闻

计算机毕业设计之学生疫情信息管理系统

计算机毕业设计之学生疫情信息管理系统

学生疫情信息管理系统是学校中重要的一环,学生疫情信息管理是教师、学生获取信息的主要渠道。于是经过考虑之后决定开发基于JSP技术设计与实现了一款简洁、轻便的学生疫情信息管理系统。本系统解决了学生疫情信息管理的主要问题,包括以下多个功能模块&am…

2026/7/21 11:05:53
计算机毕业设计之学生选课网站的设计与实现

计算机毕业设计之学生选课网站的设计与实现

教育行业也在不断细化,如今市场上对于在线教育的需求急剧增多,自动化信息处理和基于网络的信息交互方式已被广泛应用。现在学生信息管理基本上都是交由计算机进行管理和选课,高等学校管理已成为整个教育体系中的重要组成部分。虽然信息技术广…

2026/7/21 11:05:53
如何快速获取学术文献PDF:Zotero-SciHub插件的终极解决方案

如何快速获取学术文献PDF:Zotero-SciHub插件的终极解决方案

如何快速获取学术文献PDF:Zotero-SciHub插件的终极解决方案 【免费下载链接】zotero-scihub A plugin that will automatically download PDFs of zotero items from sci-hub 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-scihub 你是否曾经花费数小…

2026/7/21 11:05:53
如何快速搭建Sunshine游戏串流服务器:5步实现跨设备游戏自由

如何快速搭建Sunshine游戏串流服务器:5步实现跨设备游戏自由

如何快速搭建Sunshine游戏串流服务器:5步实现跨设备游戏自由 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你是否想过在客厅大屏上玩PC游戏,或者在平板上…

2026/7/21 11:05:53
计算机毕业设计之学生信息管理系统设计与实现

计算机毕业设计之学生信息管理系统设计与实现

学生信息管理系统是学校中重要的一环,于是经过考虑之后决定开发基于JSP技术设计与实现了一款简洁、轻便的学生信息管理系统。本系统解决了课程信息的主要问题,包括以下多个功能模块:课程信息、课程选择、课程成绩、奖惩记录、学生学籍、学生请…

2026/7/21 11:05:53
如何在ARM设备上高效运行x86_64程序:Box64终极兼容方案实战指南

如何在ARM设备上高效运行x86_64程序:Box64终极兼容方案实战指南

如何在ARM设备上高效运行x86_64程序:Box64终极兼容方案实战指南 【免费下载链接】box64 Box64 - Linux Userspace x86_64 Emulator with a twist, targeted at ARM64, RV64 and LoongArch Linux devices 项目地址: https://gitcode.com/gh_mirrors/bo/box64 …

2026/7/21 11:00:53

月新闻