草庐IT

【Prism系列】 Prism实现依赖注入

code bean 2023-04-11 原文

安装

首先安装Prism.Unity包

项目改造:

修改App.xaml

  1. 屏蔽掉StartupUri="MainWindow.xaml"
  2. 添加 xmlns:prism="http://prismlibrary.com/"
  3. 修改Application标签为prism:PrismApplication,prism:PrismApplication也是继承自Application,她对Application进行了扩展
<prism:PrismApplication x:Class="TestSpectrum.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:TestSpectrum"
             xmlns:prism="http://prismlibrary.com/"        
             >
    <!--StartupUri="MainWindow.xaml"-->
    <Application.Resources>

    </Application.Resources>
</prism:PrismApplication>

修改App.xaml.cs

  1.  继承 PrismApplication
  2.  重写以下方法

注意这里我们可以直接通过Container.Resolve从容器中获取实例

public partial class App : PrismApplication
{
    protected override Window CreateShell()
    {
        // 通过容器创造主界面实例
        return Container.Resolve<MainWindow>();
    }

    // 初始化Shell(主窗口)的时候执行这个方法
    protected override void InitializeShell(Window shell)
    {
        // 可以用于实现登录逻辑,以下是伪代码

        var loginWin = Container.Resolve<LoginWindow>();// 创建一个窗口对象
        if (loginWin == null || loginWin.ShowDialog() != true)// 以模态窗口的方式打开这个窗口对象
        {
            // 不需要App的属性ShutdownMode配合
            Application.Current.Shutdown();
            // 如果没有强行退出的话,打开主窗口
        }
    }


    /// <summary>
    /// 用于注册一些内容
    /// </summary>
    /// <param name="containerRegistry"></param>
    /// <exception cref="NotImplementedException"></exception>
    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterSingleton(typeof(OmniDriver.NETWrapper));
        containerRegistry.RegisterSingleton<ISpectrum, SpectrumFlame>();
        //Prism.Unity.UnityContainerExtension
    }
}

容器注册

这里我们重点关注,RegisterTypes这个方法,它会在程序启动后被框架调用。

传进来一个参数,containerRegistry,它的类型其实是UnityContainerExtension,这里用接口IContainerRegistry来接收这个变量。这里注意UnityContainerExtension实现了多个接口,其中就包含了包含了IContainerRegistry 和 IContainerProvider(后面会说到)。

当 RegisterTypes别调用后,我们利用containerRegistry向容器注册内容,这些注册了的内容,就可以在其他地方实现自动注入了。

IOC和工厂模式的思路是一样的,将需要new的地方(程序不稳定的地方)统一隔离在一个地方。IOC其实就是一个超级工厂。

这里我们用RegisterSingleton进行注册。

containerRegistry.RegisterSingleton(typeof(OmniDriver.NETWrapper));
containerRegistry.RegisterSingleton<ISpectrum, SpectrumFlame>();

单独类注册

第一句注册了单个类,那么我们可以利用特性[Unity.Dependency] 自动注入这个类的实例到其他的类。 

接口和实现类的注册

第二句注册了一个接口和对应的实现类,那么我们可以自动注入接口,程序运行起来后,容器会自动帮我们实例化这个类并赋值給该接口。

 注册的生命周期,Register和RegisterSingleton

这里我们也可以用Register,区别在于实例的生命周期,RegisterSingleton表示注册的实例时单例模式,每次找容器取实例时,取到的是第一次的实例化的那一个,如果是Register注册的实例则下次找容器要的话得到是新的实例。

之前,我们直接通过Container.Resolve<MainWindow>();拿到的对象呢?它并没有注册?那再次拿的话会是同一个吗?我们做个实验。

 也就是说,没有注册时,Container.Resolve<MainWindow>();每次拿到的时新的对象,

但是如果我加上一句:containerRegistry.RegisterSingleton<MainWindow>();

 再次运行:

 程序启动之后,我再想注册怎么办?

目前我们只能通过RegisterTypes回调来注册,要想在其他地方注册,怎么办?关键是拿到对象,containerRegistry。

我们可以先利用 Application.Current as App 得到当前的App对象,然后app对象里有个Container属性,这个和之前的containerRegistry其实就是一个对象(都是UnityContainerExtension的实例),不过它此时的类型是IContainerProvider,我们可以直接将其转换成IContainerRegistry,这样就可以调用注册方法了,如下:

var a = System.Windows.Application.Current as App;
var c = (IContainerRegistry)a.Container;
c.RegisterSingleton<ISpectrum, SpectrumFlame>();

当一个接口有多个实现类时如何注册?

我们直接这么写会怎样?

这样的话,第二个会覆盖第一个,也就是自动注入时,会注入SpectrumMini,而不是SpectrumMini。那该怎么办?那就加个名字!!

再次运行发现直接报错了!

 因为此时,自动注入懵逼了。有了名字它不知道具体应该注入哪个了。

我们先换一种思路,不通过属性注入,而是通过容器去拿:

var app = (System.Windows.Application.Current as App).Container;
spectrum = app.Resolve<ISpectrum>("Mini");
Console.WriteLine(spectrum.GetType().ToString());
spectrum = app.Resolve<ISpectrum>("Flame");
Console.WriteLine(spectrum.GetType().ToString());

 带上这个名字就好了,不会报错了!

但是回过头看自动注入,就不行了吗?我网上找了一圈也没找到。突然直觉告诉我,我可以这么试试:

果然,这样也是可以的,非常完美~~~~

有关【Prism系列】 Prism实现依赖注入的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

  3. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  4. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  5. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  6. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  7. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  8. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  9. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  10. 阿里云RDS——产品系列概述 - 2

    基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于

随机推荐