Unity浅析

在分析PRISM项目的时候, 发现里面用到了Unity 这个Component, 主要用于依赖注入的。由于对其不熟悉,索性分析了一下,记载在此,以作备忘。

任何事物的出现,总有它独特的原因,Unity也是如此。

在Unity产生之前,我们是这么做的

在远古的时候,当我们需要在一个类A中引用另一个类B的时候,总是将类B的实例放置到类A的构造函数中,以便在初始化类A的时候,得到类B的实例。

1    public class A
2     {
3         B b;
4         public A()
5         {
6             B = new B();
7         }
8     }

 

但是,当项目稍微大一点的时候,维护起来就显得异常吃力,尤其是当有Code Change的时候,如果类B有了一些修改(比如加入了带参构造等等),那么这种修改和测试将是异常难受的。

所以,为了解决最原始的问题,我们开始在类A的外部获取类B的实例,以便能够减轻依赖:

1  public class A
2     {
3         B b;
4         public A(B _b)
5         {
6             This.b = _b;
7         }
8     }

 

这样,只需要在外部实例化B,然后传入类A即可。这样做,虽然比原始做法方便了许多,然是在类A内部,依然存在着对类B的依赖。由于类B在系统中是唯一的,所以说当有许多个类似于类B的对象需要进行初始化的时候,这种工作量…谁能够想象呢?

有了问题,才会思考变化,于是接口开始在这方面体现他的威力了:

1    public class A
2     {
3         IMyObject myObj;
4         public A(IMyObject myObj)
5         {
6             this.myObj = myObj;
7         }
8     }

 

将相似的操作抽出来,放入接口中。现在,你就拥有了许多可以操纵的类对象(继承了IService接口的类)。并且采用接口以后,你可以更加容易的进行开发和测试,并且维护起来也相对简单。比如,如果你想测试接口中的DataExtracting功能,那么你完全可以写一个类继承自这个接口,只实现DataExtracting功能即可,简单,方便。

在Unity产生之后,我们是这么做的

现在,Unity将这种操作更加的简单化,我们可以理解为这样,Unity将继承了接口的类进行了横切,然后提供了还原的方法:

进行依赖注入:

 1    UnityContainer container = new UnityContainer();
 2 
 3         private void button1_Click(object sender, EventArgs e)
 4         {
 5             container.RegisterType<IMyObject, MyObjectFirstImplementation>(DependencyRegistrationKeys.FirstImplementation);
 6             container.RegisterType<IMyObject, MyObjectSecondImplementation>(DependencyRegistrationKeys.SecondImplementation);
 7 
 8             container.RegisterType<IMyObject, MyObjectThirdImplementation>();
 9             container.RegisterType<IMyObject, MyObjectFirstImplementation>();
10 
11         }

 

 

还原实体类:

 1 public MyObjectFactory(UnityContainer unityContainer)
 2         {
 3             this.unityContainer = unityContainer;
 4         }
 5 
 6         public UnityContainer unityContainer;
 7 
 8         public IMyObject Create(string objKey)
 9         {
10             return unityContainer.Resolve<IMyObject>(objKey);
11         }
12  

 

最后给出一个例子作为参考,这个例子主要是讲解Unity如何进行注册对象以及还原的:

实例说明

首先,我们需要有一个IMyObject接口,然后有三个类继承自此对象:

接口:

1 namespace UnityDaemon
2 {
3     public interface IMyObject
4     {
5         string DoSomething();
6     }
7 }

 

MyObjectFirstImplementation类:

 1 namespace UnityDaemon
 2 {
 3     public class MyObjectFirstImplementation:IMyObject
 4     {
 5         public string DoSomething()
 6         {
 7             return "You call me ? I am the first one,  I am from MyObjectFirstImplementation!! ";
 8         }
 9     }
10 }

 

MyObjectSecondImplementation类:

 1 namespace UnityDaemon
 2 {
 3     public class MyObjectSecondImplementation:IMyObject
 4     {
 5         public string DoSomething()
 6         {
 7             return "You call me ? I am the second one, I am from MyObjectSecondImplementation!! ";
 8         }
 9     }
10 }

 

MyObjectThirdImplementation类:

 1 namespace UnityDaemon
 2 {
 3     public class MyObjectThirdImplementation:IMyObject
 4     {
 5         public string DoSomething()
 6         {
 7             return  "I am the third. Do whatever you want to ~~~";
 8         }
 9     }
10 }

 

当然,这里我们还可以增加更多的类...

然后,我们需要创建一个Factory,用于根据Object名称来还原对象:

 1 using Microsoft.Practices.Unity;
 2 
 3 namespace UnityDaemon
 4 {
 5     public class MyObjectFactory
 6     {
 7         public MyObjectFactory() { }
 8 
 9         public MyObjectFactory(UnityContainer unityContainer)
10         {
11             this.unityContainer = unityContainer;
12         }
13 
14         public UnityContainer unityContainer;
15 
16         public IMyObject Create(string objKey)
17         {
18             return unityContainer.Resolve<IMyObject>(objKey);
19         }
20     }
21 }

 

这样做完之后,我们就可以来使用了,我利用Winform做的界面,Button1用来注册类型,Button2用来还原有名称的对象,Button3用来还原无名称的对象:

 1 using System;
 2 using System.Windows.Forms;
 3 using Microsoft.Practices.Unity;
 4 
 5 namespace UnityDaemon
 6 {
 7     public partial class MainFrm : Form
 8     {
 9         UnityContainer container;
10 
11         public MainFrm()
12         {
13             InitializeComponent();
14             container = new UnityContainer();
15         }
16 
17         private void button1_Click(object sender, EventArgs e)
18         {
19             container.RegisterType<IMyObject, MyObjectFirstImplementation>(DependencyRegistrationKeys.FirstImplementation);
20             container.RegisterType<IMyObject, MyObjectSecondImplementation>(DependencyRegistrationKeys.SecondImplementation);
21 
22             container.RegisterType<IMyObject, MyObjectThirdImplementation>();
23             container.RegisterType<IMyObject, MyObjectFirstImplementation>();
24 
25         }
26 
27         private void button2_Click(object sender, EventArgs e)
28         {
29             var factory = new MyObjectFactory(container);
30             var myObj = factory.Create(DependencyRegistrationKeys.FirstImplementation);
31             string str = myObj.DoSomething();
32             MessageBox.Show(str);
33 
34             var myObj1 = factory.Create(DependencyRegistrationKeys.SecondImplementation);
35             string str1 = myObj1.DoSomething();
36             MessageBox.Show(str1);
37         }
38 
39         private void button3_Click(object sender, EventArgs e)
40         {
41             var myObj1 = container.Resolve<IMyObject>();
42 
43             MessageBox.Show(myObj1.DoSomething());
44         }
45     }
46 }

 

这样,当我们运行起来,先点击Button1的时候,三个类都被注册进了容器中。当点击Button2的时候,显示出来的结果和预想一样。当点击Button3的时候,仅仅显示了

You call me ? I am the first one,  I am from MyObjectFirstImplementation!!

原因是什么呢? 原因就在于当注册的时候,没有提供名称的话,那么解析的时候,则以最后一次注册的为准。所以这也是MyObjectThirdImplementation类中的函数没有被执行的原因。

源码下载

点击这里下载

参考连接

http://stackoverflow.com/questions/4612054/wpf-prism-what-is-a-unity-container

http://blogsprajeesh.blogspot.hk/search/label/PRISM

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

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

相关文章

WPF效果第一百九十六篇之彩色马蹄形图

上一篇又是基于ListBox改了改模板实现了点不一样的效果;今天来分享一点这些天一直摸索的好玩的效果;闲话不多扯直接看效果:1、对于各种定义就直接看下面:https://www.wigglepixel.nl/en/blog/what-are-color-spaces-color-profiles-and-gamma-correction2、关于马蹄图我找到了S…

grub4dos中的不容易理解的问题

2019独角兽企业重金招聘Python工程师标准>>> menu.lst中写有菜单&#xff0c;但又发现很多人使用BCD,是否是这样&#xff0c;通过menu.lst中的菜单引导的系统&#xff0c;是不通过BCD文件引导的&#xff0c;还是说它们是必须同时有的&#xff0c;并且要关联呢&#…

卸载wps后桌面上的office文件图标变成了白色

文章目录卸载wps后桌面上的office文件图标变成了白色第一步&#xff1a;第二步卸载wps后桌面上的office文件图标变成了白色 作者&#xff1a;wyf 第一步&#xff1a; **win(图标&#xff09;R&#xff0c;输入regedit&#xff0c;点击确定**第二步 2、找到HKEY_CLASSES_ROOT…

springboot单例模式注入对象_Spring 中经典的 9 种设计模式,打死也要记住啊!

本文转载自公众号“Java专栏1.简单工厂(非23种设计模式中的一种)2.工厂方法3.单例模式4.适配器模式5.装饰器模式6.代理模式7.观察者模式8.策略模式9.模版方法模式Spring中涉及的设计模式总结1.简单工厂(非23种设计模式中的一种)实现方式&#xff1a;BeanFactory。Spring中的Bea…

通过项目逐步深入了解Mybatis(四)

相关阅读&#xff1a; 1、通过项目逐步深入了解Mybatis<一> 2、通过项目逐步深入了解Mybatis<二> 3、通过项目逐步深入了解Mybatis<三> 本项目所有代码及文档都托管在 Github地址&#xff1a;https://github.com/zhisheng17/mybatis 延迟加载 什么是延迟加载…

超链接伪类

1.伪类样式-语法&#xff1a; a:hover{ color:#155; } 2.伪类名称 含义 a:link 为单击访问时超链接样式 a:visted 单击访问后超链接样式 a:hover 鼠标悬浮其上的超链接样式 a:active 鼠标单击未释放的超链接样式…

读两本敦煌书杂记-敦煌的历史(一)

前两天看了樊锦诗院长的讲座&#xff0c;八十几岁的高龄还讲的兴致盎然&#xff0c;虽然全长两个多小时但感觉一点不嫌长&#xff0c;听完深受感动。意犹未尽&#xff0c;又迫不及待的买了几本书来读。一本是《灿烂佛宫》&#xff0c;一本是《报恩父母经典故事》。因为我自己从…

在anaconda中安装tensorflow-GPU版本

在anaconda中安装tensorflow-GPU版本 第一步&#xff1a;去anaconda官网下载&#xff0c;我下载的是anaconda (python3.7版本&#xff09; anaconda下载链接&#xff1a;点击link 进去之后网页最下面有要下载的版本 安装的具体步骤&#xff1a;点击 link 第二步&#xff1a;…

云服务远程登录---设置安全组

对于小白来说购买了云服务不知道怎么开放端口和用xsell远程连接下面是步骤&#xff1a; 下面就可以玩耍了转载于:https://www.cnblogs.com/zhaojingyu/p/9021068.html

高程数据处理_珠峰长高了吗?新高程怎么算出来的?揭秘

珠穆朗玛峰是世界上海拔最高的山峰&#xff0c;被称为世界第三极&#xff0c;是亚洲的水塔。12月8日&#xff0c;珠穆朗玛峰最新高程公布&#xff0c;为8848.86米。珠峰长高了吗&#xff1f;怎么测算出来的&#xff1f;和以往的测量相比&#xff0c;“新”在哪里&#xff1f;就…

微服务框架开发(二)—扩展spring schema

2019独角兽企业重金招聘Python工程师标准>>> 一、实体bean的定义 回顾一下我们需要定义的4个标签 定义注册中心标签&#xff1a;<xmen:registry name"registry" regProtocol"zookeeper" address"127.0.0.1:2181" connectTimeout&q…

Linux下下载JDK

需要加特殊的前缀,不然无法下载文件 . 例如JDK8 U131 wget -c --header "Cookie: oraclelicenseaccept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.tar.gz转载于:https://w…

如何找tensorflow-gpu版本对应的cuda和cudnn

第一步 先创建一个虚拟环境&#xff08;我是在anaconda Prompt中创建&#xff09;&#xff1a;conda create -n TF1.14 python3.6 第二步 进入虚拟环境conda activate TF1.14 第三步 安装tensorflow-gpu版本 pip install tensorflow-gpu1.14.0 -i HTTPS://pypi.doubanio…

基于干净语言和好奇心的敏捷指导

\关键要点\\通过简单的问题可以挖掘出产品中包含的真正有价值的信息&#xff0c;以及我们所期望的合作方式。\\t在以“干净问题”为基础的文化中&#xff0c;没有问题会遭到嘲笑&#xff0c;而且不存在“愚蠢”的问题。\\t“尽其所能地工作”和“干净反馈”等练习可以帮助敏捷团…

origin如何绘制双y轴曲线_Origin用矩阵绘制多层曲面映射图

点击上方关注点击下方点赞【导读】怎样绘制多曲面映射图&#xff1f;1.矩阵数据的准备1.1 XYYYY型数据我们在实验中得到一张Excel表格一列X表示电场强度&#xff0c;负载量不同的多列Y又分为Pm、Pr两组。那么我们需要分别构造Pm和Pr两组XYYYY型数据表。那么全选Pr表中的XYYYY型…

北京大学Tensorflow2.0笔记

激活函数 目前很少用这个激活函数&#xff0c;因为在深度神经网络中更新参数时需要从输出层到输入层逐层进行链式求导&#xff0c;而sigmoid函数倒数值为0-0.25之间&#xff0c;链式求导需要多层导数连续相乘&#xff0c;会出现多个0-0.25之间的连续相乘&#xff0c;结果趋于零…

实现简单的shell sed替换功能

1 import sys2 3 fopen(lyrics.txt,r,encodingutf-8) #读写4 f_newopen(lyrics_new,w,encodingutf-8)5 find_strsys.argv[1]6 replace_strsys.argv[2]7 for line in f:8 if find_str in line:9 lineline.replace(find_str,replace_str) 10 f_new.write(line) …

开源新工具 Azure Developer CLI

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;5分钟)翻译自 Savannah Ostrowski 的博客今天&#xff0c;我们很高兴地宣布 Azure Developer CLI (azd) 公共预览版——一种新的开源工具&#xff0c;可加快入门Azure 所需的时间。Azure Developer CLI 提供了对开发者…

MapReduce中的InputFormat(1)概述

1 概念InputFormat用于描述输入数据的格式&#xff0c;提供以下两个功能&#xff1a;A、数据切分&#xff1a;按照某种策略将输入的数据切分成若干split&#xff0c;以便确定Map Task个数&#xff0c;以及对应的Split。B、提供数据&#xff1a;为Mapper提供输入数据&#xff0c…

oracle 修改sgamaxsize_oracle初始化内存配置参数(sga,pga,sharepool)

小白在日常工作中经常遇到数据库启动报错&#xff0c;其中80%都是跟数据库的初始化内存参数有关&#xff0c;现整理一份模板&#xff0c;以期后用1. 查出linux服务器总的内存&#xff1a;8G左右integer memTotalSizegrep ^MemTotal: /proc/meminfo | awk {print $2} 8064956…