zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    使用Jquery 来AJAX操作!
    血细胞形态异常的临床意义
    骨髓细胞检查
    保护眼睛的颜色
    php的一些技巧
    播放ASF文件无声音
    不被其他网站载入框架之内
    如何判断一个页面加载所耗费的时间
    教大家如何洗葡萄,很好吃哦!
    急性粒细胞白血病部分分化型AMLM2
  • 原文地址:https://www.cnblogs.com/android-blogs/p/6136783.html
Copyright © 2011-2022 走看看