【WPF】Prism学习(七)

Prism Dependency Injection

在这里插入图片描述

1.注册类型(Registering Types)

1.1. Prism中的服务生命周期

  • Transient(瞬态):每次请求服务或类型时,都会获得一个新的实例。
  • Singleton(单例):每次请求服务或类型时,都会获得同一个实例。
  • Scoped(作用域):在每个容器作用域中获得一个新的实例,但在特定的容器作用域内保持同一个实例。

1.2. Prism中的默认作用域

  • Prism默认不使用作用域,除了在Prism.Maui中,它会为每个页面创建一个作用域。这种作用域用于INavigationServiceIPageDialogServiceIDialogService等服务。

1.3. 与ASP.NET Core的比较

  • 如果你熟悉ASP.NET Core,你可能知道三种基本的依赖注册类型:Transients、Singletons和Scoped Services。与Web环境中许多服务围绕用户请求进行作用域划分不同,桌面和移动应用通常只处理单个用户。因此,我们需要决定服务是作为整个应用中重复使用的单个实例,还是每次请求时创建新实例,并在完成后由垃圾回收器清理内存。

1.4. Prism对命名服务注册的要求

  • Prism严格要求使用命名服务注册。这使得Prism能够注册页面以供导航,并在之后根据URI片段(如MyMasterDetailPage/NavigationPage/ViewA)解析它。任何不支持命名服务的依赖注入容器都不能被Prism团队官方实现。

2.注册瞬态(Transient)服务

瞬态服务是指每次请求服务或类型时都会创建一个新的实例。在Prism中,如果你期望每次创建服务时都生成一个新的实例,你可以通过调用Register方法并提供服务类型和服务实现类型来注册这样的服务。除非在某些情况下,直接注册具体类型(concrete type)可能是合适的。

// Where it will be appropriate to use FooService as a concrete type
containerRegistry.Register<FooService>();containerRegistry.Register<IBarService, BarService>();

具体来说,代码示例展示了两种注册瞬态服务的方式:

  1. 如果FooService是一个具体类型,并且你希望每次请求FooService时都创建一个新的实例,你可以直接使用containerRegistry.Register<FooService>();来注册。

  2. 如果IBarService是一个接口,而BarService是实现这个接口的具体类,你希望每次请求IBarService时都创建一个新的BarService实例,你可以使用containerRegistry.Register<IBarService, BarService>();来注册。

这两种方式都是在告诉Prism的依赖注入容器,当应用中需要FooServiceIBarService时,应该每次都创建一个新的实例,而不是重用已有的实例。这种方式适用于那些不需要在应用的生命周期内保持状态的服务。

3.注册单例(Singleton)服务

  1. 单例服务的定义:在应用程序中,有些服务会被多次使用。如果每次都创建一个新的实例,这将不利于内存管理。因此,更好的做法是将这些服务注册为单例,这样它们就可以在整个应用程序中被重复使用。

  2. 单例服务的内存管理:单例服务在注册时并不会立即创建实例,它们不会开始占用内存,直到应用程序第一次解析(请求)这些服务时才会创建实例。

  3. 注册单例服务的代码示例

// Where it will be appropriate to use FooService as a concrete type
containerRegistry.RegisterSingleton<FooService>();containerRegistry.RegisterSingleton<IBarService, BarService>();
  • containerRegistry.RegisterSingleton<FooService>();:这行代码将FooService注册为一个单例服务。这意味着在整个应用程序中,FooService只会有一个实例。
  • containerRegistry.RegisterSingleton<IBarService, BarService>();:这行代码将接口IBarService和它的实现BarService注册为一个单例服务。这样,任何时候请求IBarService,都会返回同一个BarService实例。

在Prism框架中,对于那些需要在整个应用程序中保持状态或频繁使用的服务,注册为单例是一种有效的做法,它有助于优化内存使用和提高应用程序性能。

4.注册服务实例

  1. 注册服务实例:通常情况下,我们会通过提供服务类型和服务实现类型来注册单例。但是,有时候我们可能需要直接创建一个服务实例,并将其注册为特定的服务。例如,如果我们有一个接口IFoo和一个实现FooImplementation,我们可以直接创建FooImplementation的实例,并将其注册为IFoo的服务实例。

    containerRegistry.RegisterInstance<IFoo>(new FooImplementation());
    
  2. 使用插件中的当前实例:有时候,我们可能想要注册来自某个插件的当前实例。以James Montemagno的MonkeyCache插件为例,我们首先设置Barrel.ApplicationId为一个唯一的名称,然后注册Barrel.Current作为IBarrel的服务实例。

    Barrel.ApplicationId = "your_unique_name_here";
    containerRegistry.RegisterInstance<IBarrel>(Barrel.Current);
    

在Prism框架中,除了通过服务类型和服务实现类型注册服务外,还可以直接注册服务实例,这在集成第三方插件或需要直接控制服务实例时非常有用。

5.检查一个服务是否已经被注册

if (containerRegistry.IsRegistered<ISomeService>())
{// Do something...
}
  1. 检查服务是否注册

    • 在编写Prism模块或插件时,开发者可能需要检查某个服务是否已经被注册到依赖注入容器中。这可以通过containerRegistry.IsRegistered<ISomeService>()方法来实现,其中ISomeService是你想要检查的服务接口。
  2. 基于服务注册状态执行操作

    • 如果服务已经被注册,你可以执行一些特定的操作。例如,如果IsRegistered<ISomeService>()返回true,你可以在大括号{}中编写相应的代码来处理这种情况。
  3. 注意事项

    • 如果你在Prism模块中有一个对特定服务的硬依赖,你应该通过构造函数注入该服务。这样做的好处是,如果在模块初始化时缺少该服务类型,将会抛出异常。这有助于在开发过程中及早发现问题。
    • 只有当你的意图是注册一个默认实现时,才应该使用IsRegistered来检查服务是否已经注册。这意味着,如果服务尚未注册,你可以使用IsRegistered检查后,注册一个默认的服务实现。

6.延迟解析(Lazy Resolution)服务

  1. 延迟解析服务:在Prism框架中,你可以像这样注册服务:containerRegistry.Register<IFoo, Foo>()。有些开发者可能希望节省内存,延迟加载服务,可以将其作为Func<IFoo>Lazy<IFoo>来实现。Prism 8原生支持这种功能。要实现这一点,你只需要在你的ViewModel或Service中添加相应的参数,如下所示:

    public class ViewAViewModel
    {public ViewAViewModel(Func<IFoo> fooFactory, Lazy<IBar> lazyBar){}
    }
    
  2. 注意服务注册类型:当你使用单例服务时,通常不建议使用Lazy<T>Func<T>进行解析。例如,IEventAggregator是一个单例服务,这意味着整个应用程序中只使用一个事件聚合器实例。如果你使用Lazy<T>Func<T>,最终可能会使用更多的内存,并且可能会因为延迟解析而影响性能,而不是直接请求服务。

这段内容强调了在Prism框架中实现延迟加载服务的方法,以及在使用单例服务时应避免使用Lazy<T>Func<T>,以节省内存和提高性能。

7.全部解析(Resolve All)

  1. Resolve All(全部解析):有些开发者可能需要注册同一个服务契约的多个实现,并期望在需要时能够解析出所有这些实现。这是一种常见的用例,例如Shiny框架在其一些委托接口中使用了这种模式。

  2. 构建模块化代码:通过这种方式,开发者可以构建更模块化的代码,因为可以对同一个事件做出响应,但是每次只处理一小部分(bite sized chunks)。

  3. 注册过程:对于这种特性,注册过程中没有什么特别的步骤。开发者只需要在构造函数中注入IEnumerable<T>接口即可。例如,如果你有一个IFoo服务接口,并且有多个实现,你可以这样注入:

    public class SomeService
    {public SomeService(IEnumerable<IFoo> fooCollection){// 这里的fooCollection将包含所有IFoo的实现}
    }
    
  4. 支持情况:目前,只有DryIoc依赖注入容器支持这个特性。对于使用Unity容器的开发者来说,一旦Unity容器发布6.0版本,这个特性可能会变得可用。

相关链接

  • 介绍(Introduction)
  • 命令(Commands)
    • 命令(Commanding)
    • 复合命令(Composite Commands)
    • 异步命令(Async Commands)
    • 错误处理(Error Handling)
  • 依赖注入(Dependency Injection)
    • 依赖注入(Dependency Injection)
    • 注册类型(Registering Types)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/474528.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器数据恢复—热备盘未激活导致硬盘掉线的raid5阵列崩溃的数据恢复案例

服务器数据恢复环境&#xff1a; 某品牌X3850服务器中有一组由数块SAS硬盘组建的RAID5阵列&#xff0c;该阵列中有一块盘是热备盘。操作系统为linux redhat&#xff0c;上面跑着一个基于oracle数据库的oa。 服务器故障&#xff1a; 服务器raid5阵列中有一块硬盘离线&#xff0…

ADS 2022软件下载与安装教程

“ 本文以最新的Advanced Design System 2022为例介绍ADS软件的安装及crack教程 ” ADS 简介 先进设计系统 Advanced Design system&#xff08;ADS&#xff09;Agilent Technologies 是领先的电子设计自动化软件&#xff0c;适用于射频、微波和信号完整性应用。ADS 是获得商…

Chrome 浏览器 131 版本新特性

Chrome 浏览器 131 版本新特性 一、Chrome 浏览器 131 版本更新 1. 在 iOS 上使用 Google Lens 搜索 自 Chrome 126 版本以来&#xff0c;用户可以通过 Google Lens 搜索屏幕上看到的任何图片或文字。 要使用此功能&#xff0c;请访问网站&#xff0c;并点击聚焦时出现在地…

Unity 编辑器下 Android 平台 Addressable 加载模型粉红色,类似材质丢失

Unity 编辑器下 Android 平台 Addressable 加载模型粉红色&#xff0c;类似材质丢失 Addressable Play Mode Script加载模式 选择 Use Existiing Build 1.Unity 切换到 PC 平台&#xff0c;执行 Addressable Build 运行&#xff0c;加载 bundle 内的预制体 显示正常 2.Unit…

独立站干货:WordPress主机推荐

WordPress作为全球最受欢迎的独立站建设平台&#xff0c;提供了灵活性和强大的功能&#xff0c;使得建站变得简单而高效。本文将为您详细介绍WordPress建站的流程&#xff0c;并推荐几款实测后觉得好用的主机商。 WordPress建站流程 域名注册 首先需要注册一个域名&#xff0c…

每日OJ题_牛客_天使果冻_递推_C++_Java

目录 牛客_天使果冻_递推 题目解析 C代码 Java代码 牛客_天使果冻_递推 天使果冻 描述&#xff1a; 有 n 个果冻排成一排。第 i 个果冻的美味度是 ai。 天使非常喜欢吃果冻&#xff0c;但她想把最好吃的果冻留到最后收藏。天使想知道前 x个果冻中&#xff0c;美味…

C++AVL平衡树

1.AVL平衡树节点定义 每一个节点都配左右孩子和父节点&#xff0c;以及平衡因子和其所对应的值。 template<class K, class V> struct AVLTreeNode {// 需要parent指针&#xff0c;后续更新平衡因子可以看到pair<K, V> _kv;AVLTreeNode<K, V>* _left;AVLTr…

Vue3 pinia使用

Pinia 是一个现代的状态管理库&#xff0c;专为 Vue 3 设计。它提供了一种简单、直观的方式来管理应用中的全局状态 (就是不同组件都希望去共享的一些变量,函数等)。Pinia 的设计灵感来自于 Vuex&#xff08;Vue 2 的状态管理库&#xff09;&#xff0c;但进行了许多改进&#…

PHP开发全新UI多语言多商户跨境商城源码、支持一键铺货、一键下单

商家可在平台产品库选品&#xff0c;一键铺货到自己商店&#xff0c;用户下单后&#xff0c;商家提交订单给平台&#xff0c;扣除商家供货价所需余额&#xff0c;提交后由平台发货&#xff0c;收货后订单金额结算给商家. 源码开源完整&#xff0c;一切能跑通的逻辑流程都可以二…

移动应用开发:使用Android Studio 实现登录页与注册页跳转

文章目录 前期一&#xff0c;添加UI控件触发跳转二&#xff0c;编写LoginActivity活动代码三&#xff0c;运行程序查看效果 前期 需创建两个活动页面&#xff0c;登录页和注册页&#xff0c;可参考&#xff1a;《Android Studio实现简易登录页》《Android Studio实现简易注册页…

【东莞石碣】戴尔R740服务器维修raid硬盘问题

1&#xff1a;石碣某塑料工厂下午报修一台戴尔R740服务器硬盘故障&#xff0c;催的还比较着急。 2&#xff1a;工程师经过跟用户确认故障的问题以及故障服务器型号和故障硬盘型号&#xff0c;产品和配件确认好后&#xff0c;公司仓库确认有该款硬盘现货&#xff0c;DELL 12T S…

Inpaint-Web:纯浏览器端实现的开源图像处理工具

之前在刷短视频的时候&#xff0c;经常看到一些情侣在景区拍照&#xff0c;结果被路人“抢镜”。有时男朋友会拿出手机&#xff0c;帮忙把那些路人“P”掉&#xff0c;简直是既贴心又有趣。最近我在逛 GitHub 时&#xff0c;发现了一个可以在浏览器端删除照片中部分内容的纯前端…

IDEA2023 SpringBoot整合Web开发(二)

一、SpringBoot介绍 由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。SpringBoot提供了一种新的编程范式&#xff0c;可以更加快速便捷…

技术速递|Microsoft.Extensions.VectorData 预览版简介

作者&#xff1a;Luis Quintanilla - 项目经理 排版&#xff1a;Alan Wang 我们很高兴推出 Microsoft.Extensions.VectorData.Abstractions 库&#xff0c;该库现已提供预览版。 正如 Microsoft.Extensions.AI 库为使用 AI 服务提供了一个统一层一样&#xff0c;此包为 .NET 生…

React解决保存less文件后会自动生成css文件的方法

背景&#xff1a;在项目中使用了less&#xff0c;用的是vscode中esay less插件&#xff0c;但在每次保存.less文件时&#xff0c;都会在对应的同级文件夹内生成一个.css文件&#xff0c;如何避免这样的情况呢&#xff1f; 解决办法&#xff1a;在同级目录下的.vscode文件夹&…

初级数据结构——栈与队列的互相实现

目录 前言一、用栈实现队列操作&#xff1a;c代码模版经典例题 二、用队列实现栈操作&#xff1a;c代码模版经典例题 三、总结四、结语 前言 通过我之前的作品已经初步理解了栈和队列的数据结构&#xff0c;这期我们来学习如何实现这两个数据结构的互相转换。在计算机科学中&a…

Qt的一个基本用户登录界面编写|| 从0搭建QT的信号与槽的应用案例 ||Qt样式表的应用

目录 1.新建1个qt项目&#xff0c;基类选中QWidget 2.ui文件布局 3.头文件 3.1 explicit的作用 具体解释 示例 4.cpp源文件 5.信号与槽的应用 6.qt实现效果 7.qt样式表的应用 1.新建1个qt项目&#xff0c;基类选中QWidget 2.ui文件布局 3.头文件 #ifndef WIDADMINLO…

【Apache Paimon】-- 2 -- 核心特性 (0.9.0)

目录 1、实时更新 1.1、实时大批量更新 1.2、支持定义合并引擎 1.3、支持定义更新日志生成器 2、海量数据追加处理 2.1、append table 2.2、快速查询 3、数据湖功能&#xff08;类比&#xff1a;hudi、iceberg、delta&#xff09; 3.1、支持 ACID 事务 3.2、支持 Time…

webpack配置

4-3vue-loader测试_哔哩哔哩_bilibili 一.新建文件夹vue_todo&#xff0c;vscode打开 二.ctrl打开终端&#xff0c;输入npm init -y&#xff0c;快速生成一个默认的package.json文件 之后左边出现项目初始化文件package.json 三.接下来需要webpack完成打包&#xff0c;所以安装…

5.STM32之通信接口《精讲》之USART通信---实验串口接收程序

根据上节&#xff0c;我们一已经完成了串口发送程序的代码&#xff0c;并且深入的解析探索了串口的原理&#xff0c;接下来&#xff0c;Whappy小编将带领大家进入串口接收程序的探索与实验&#xff0c;并将结合上一节串口发送一起来完成串口的发送和接收实验。 上来两张图 上图…