【WPF】Prism学习(七)

news2024/11/20 5:44:22

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.coloradmin.cn/o/2243838.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

.NET6 WebApi第1讲:VSCode开发.NET项目、区别.NET5框架【两个框架启动流程详解】

一、使用VSCode开发.NET项目 1、创建文件夹&#xff0c;使用VSCode打开 2、安装扩展工具 1>C# 2>安装NuGet包管理工具&#xff0c;外部dll包依靠它来加载 法1》&#xff1a;NuGet Gallery&#xff0c;注意要启动科学的工具 法2》NuGet Package Manager GUl&#xff0c…

【Homework】【7】Learning resources for DQ Robotics in MATLAB

阻尼伪逆使系统在任务空间奇异性方面具有一定的鲁棒性 阻尼伪逆 阻尼伪逆是SVD&#xff08;奇异值分解&#xff09;逆矩阵的一种有趣替代方法&#xff0c;它使系统在任务空间奇异性方面具有一定的鲁棒性。其主要思想是对任意&#xff08;可能为奇异的&#xff09;矩阵 B ∈ …

新一代API开发工具,让API调试更快 更简单

新一代API开发工具 代理调试 请求测试一站式解决方案 Reqable Fiddler Charles Postman, 让API调试更快 &#x1f680; 更简单 &#x1f44c; 直接上下载地址 根据系统,下载对应的版本即可 https://reqable.com/zh-CN/download/

详细解析STM32 GPIO引脚的8种模式

目录 一、输入浮空&#xff08;Floating Input&#xff09;&#xff1a;GPIO引脚不连接任何上拉或下拉电阻&#xff0c;处于高阻态 1.浮空输入的定义 2.浮空输入的特点 3.浮空输入的应用场景 4.浮空输入的缺点 5.典型配置方式 6.注意事项 二、输入上拉&#xff08;Inpu…

对于 unix 系统管理员来说,了解 VIM 有多重要?

对于 Unix 系统管理员来说&#xff0c;掌握 VIM 的重要性不言而喻。VIM 作为 Unix 系统中默认的文本编辑器&#xff0c;几乎在所有 Unix 系统中都预装&#xff0c;这使得系统管理员必须熟练使用它来编辑配置文件、编写脚本等。 VIM 强大的功能和灵活性&#xff0c;使得它能够满…

containerd使用

一、ctr命令 1.查看命名空间 ctr namespace ls 2.查看特定命名空间镜像 ctr -n k8s.io images ls 3.查看特定命名空间容器 ctr -n k8s.io container ls 注意&#xff1a;该项与docker不同&#xff0c;container查看容器是所有的容器无论有没有启动&#xff0c;只要创建了的…

Python 数据结构对比:列表与数组的选择指南

文章目录 &#x1f4af;前言&#x1f4af;Python中的列表&#xff08;list&#xff09;和数组&#xff08;array&#xff09;的详细对比1. 数据类型的灵活性2. 性能与效率3. 功能与操作4. 使用场景5. 数据结构选择的考量6. 实际应用案例7. 结论 &#x1f4af;小结 &#x1f4af…

在Q-Studio中进行OTX脚本的开发、仿真与调试

一 背景 现如今&#xff0c;随着车辆中电子器件和软件数量的快速增加&#xff0c;在车辆研发、生产、测试及售后阶段需要进行的车载测试工作越来越多、越来越复杂&#xff0c;呈现指数级增长的趋势。以往常用的手动测试方式已完全无法满足现如今的测试需求了&#xff0c;由此推…

Cursor安装Windows / Ubuntu

一、安装 1、下载软件 2、安装依赖 #安装fuse sudo apt-get install fuse3、将cursor添加到应用程序列表 sudo mv cursor-0.42.5x86_64.AppImage /opt/cursor.appimage #使用自己版本号替换 sudo chmod x /opt/cursor.appimage #给予可执行权限 sudo nano /usr/share/applic…

NLP论文速读(多伦多大学)|利用人类偏好校准来调整机器翻译的元指标

论文速读|MetaMetrics-MT: Tuning Meta-Metrics for Machine Translation via Human Preference Calibration 论文信息&#xff1a; 简介&#xff1a; 本文的背景是机器翻译&#xff08;MT&#xff09;任务的评估。在机器翻译领域&#xff0c;由于不同场景和语言对的需求差异&a…

Docker部署Kafka集群,增加 SASL_SSL认证,并集成到Spring Boot,无Zookeeper版

1&#xff0c;准备好Kafka 镜像包&#xff1a; bitnami/kafka:3.9.0 镜像资源包 2&#xff0c;准备好kafka.keystore.jks 和 kafka.truststore.jks证书 具体操作可参考&#xff1a; Docker部署Kafka SASL_SSL认证&#xff0c;并集成到Spring Boot-CSDN博客 3&#xff0c;配置…

Git 分⽀规范 Git Flow 模型

前言 GitFlow 是一种流行的 Git 分支管理策略&#xff0c;由 Vincent Driessen 在 2010 年提出。它提供了一种结构化的方法来管理项目的开发、发布和维护&#xff0c;特别适合大型和复杂的项目。GitFlow 定义了一套明确的分支模型和工作流程&#xff0c;使得团队成员可以更有效…

shell脚本命令1,保姆级别---清风

声明&#xff1a; 本文的学习内容来源于B站up主“泷羽sec”视频“蓝队基础之网络七层杀伤链”的公开分享&#xff0c;所有内容仅限于网络安全技术的交流学习&#xff0c;不涉及任何侵犯版权或其他侵权意图。如有任何侵权问题&#xff0c;请联系本人&#xff0c;我将立即删除相…

MySQL扩展varchar字段长度能否Online DDL

目录 问题场景 Online DDL 简介 场景复现 DBdoctor快速识别 Online DDL 总结 问题场景 在MySQL数据库中&#xff0c;DDL变更可以通过两种算法实现&#xff1a;Copy算法和In-Place算法。Copy算法会复制整个表&#xff0c;这可能导致长时间的写入阻塞&#xff0c;从而严重影…

低成本出租屋5G CPE解决方案:ZX7981PG/ZX7981PM WIFI6千兆高速网络

刚搬进新租的房子&#xff0c;没有网络&#xff0c;开个热点&#xff1f;续航不太行。随身WIFI&#xff1f;大多是百兆级网络。找人拉宽带&#xff1f;太麻烦&#xff0c;退租的时候也不能带着走。5G CPE倒是个不错的选择&#xff0c;插入SIM卡就能直接连接5G网络&#xff0c;千…

港大ArcLab最新开源DEIO:第一个学习与传统非线性图优化紧密结合的单目事件惯性里程计

原文链接&#xff1a;港大ArcLab最新开源DEIO&#xff1a;第一个学习与传统非线性图优化紧密结合的单目事件惯性里程计 导读 本文介绍了一种名为 DEIO&#xff08;Deep Event Inertial Odometry&#xff09;的新型单目深度事件惯性里程计框架。该方法创新性地将深度学习与传统…

基于麒麟服务器操作系统V10版本,部署Nginx服务、MySql服务搭建PHP环境,实现静态网站平台的搭建。

一、环境准备 关闭防火墙。 查看当前防火墙的状态 systemctl status firewalld Copy 如果防火墙的状态参数是inactive,则防火墙为关闭状态。 如果防火墙的状态参数是active,则防火墙为开启状态。 关闭防火墙。 如果您想临时关闭防火墙,需要运行以下命令: systemctl…

【priority_queue的使用及模拟实现】—— 我与C++的不解之缘(十六)

前言 ​ priority_queue&#xff0c;翻译过来就是优先级队列&#xff0c;但是它其实是我们的堆结构&#xff08;如果堆一些遗忘的可以看一下前面的文章复习一下【数据结构】二叉树——顺序结构——堆及其实现_二叉树顺序结构-CSDN博客&#xff09;&#xff0c;本篇文章就来使用…

在AndroidStudio中新建项目时遇到的Gradle下载慢问题,配置错的按我的来,镜像地址不知道哪个网页找的,最主要下载要快

android-studio-2024.2.1.11-windows Android 移动应用开发者工具 – Android 开发者 | Android Developers https://r4---sn-j5o76n7z.gvt1-cn.com/edgedl/android/studio/install/2024.2.1.11/android-studio-2024.2.1.11-windows.exe?cms_redirectyes&met1731775…

《Java核心技术 卷I》用户界面中首选项API

首选项API 在桌面程序中&#xff0c;通常都会存储用户首选项&#xff0c;如用户最后处理的文件、窗口的最后位置等。 利用Properties类可以很容易的加载和保存程序的配置信息&#xff0c;但有以下缺点&#xff1a; 有些操作系统没有主目录概念&#xff0c;很难为匹配文件找到…