微软企业库5.0 学习之路——第十步、使用Unity解耦你的系统—PART2——了解Unity的使用方法(1)
在上一篇文章中,我简单介绍Unity的一些背景知识、为什么要使用Unity和使用Unity有什么好处。今天将继续学习Unity,主要是了解Unity的一些常见的使用方法。
本篇文章将主要介绍:
Unity中的UnityContainer基本使用介绍,包括UnityContainer类的常用方法介绍,并且通过几个小例子来介绍具体的使用方法,这些例子都会以代码及配置文件两种方式来实现。
从UnityContainer(Unity容器)这个类的名称中我们就可以看出其是Unity最重要的类,UnityContainer就像Unity 的一个司令部,而一个个对象就像一名名士兵,每个士兵来去都需要通过UnityContainer来管理,其掌管了所有对象的依赖关系,所有对象的创建都 会通过这个Unity容器来创建,,同时也可以说是一个外交部,对于我们开发者,我们不需要关心内部是怎么实现的,我们只需要事先设置好对象之间的关系, 然后在需要的时候告诉UnityContainer我需要什么,UnityContainer就会将我们需要的直接发给我们。(这些比喻可能不正确,但是 是我能想到的最好的比喻了)
使用代码实现对象关联注册:
首先来看一个简单的例子:
public interface IClass { void ShowInfo(); } public class MyClass : IClass { public MyClass() { } public void ShowInfo() { Console.WriteLine("这个是我的班级"); } } 具体调用: 1 2 3 4 5 static void Main(string[] args) { IClass classInfo = new MyClass(); classInfo.ShowInfo(); }
这个是最常见的接口及其实现类的使用方法,定义一个接口,然后再定义一个类来实现这个接口,然后在具体使用的过程中,可以通过new关键字来实例化具体来 实现接口,虽然没有语法上的问题,但是这样会造成紧耦合,如果一旦具体的实现类发生了改变,则就需要修改代码,而且如果这种类似的代码很多,则会导致整个 项目的变动,甚至出现异常,所以我们需要使用IOC来解耦,具体代码如下:
public static void ContainerCode() { IUnityContainer container = new UnityContainer(); container.RegisterType<IClass, MyClass>(); //另一种注册方法,不过没有RegisterType<>()方法来的方便 //container.RegisterType(typeof(IClass), typeof(MyClass)); IClass classInfo = container.Resolve<IClass>(); //另一种通过container获取具体对象的方法 //IClass classInfo = container.Resolve(typeof(IClass)); classInfo.ShowInfo(); }
使用Unity来管理对象与对象之间的关系可以分为以下几步:
1、创建一个UnityContainer对象。
2、通过UnityContainer对象的RegisterType方法来注册对象与对象之间的关系。
3、通过UnityContainer对象的Resolve方法来获取指定对象关联的对象。
使用配置文件来实现对象关系注册:
以上是通过代码的方式来注册对象之间的关系,但是对于一个项目来说,正式部署后,由于代码都编译成DLL,如果要修改依赖关系则修改代码并重新编译,相对来说太麻烦了,所以Unity还提供配置文件配置的方式来配置对象之间的关系,配置如下:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/> </configSections> <unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> <alias alias="IClass" type="UnityStudyConsole.IDemo.IClass, UnityStudyConsole" /> <alias alias="MyClass" type="UnityStudyConsole.Demo.MyClass, UnityStudyConsole" /> <container> <register type="IClass" name="ConfigClass" mapTo="MyClass" /> </container> </unity> </configuration>
具体代码调用如下:
public static void ContainerConfiguration() { IUnityContainer container = new UnityContainer(); //获取指定名称的配置节 UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); //默认方法,默认获取名称为"unity"配置节下配置信息 container.LoadConfiguration(); //获取已命名的配置节<container name="FirstClass">下的配置信息 container.LoadConfiguration("FirstClass"); //获取特定配置节下配置信息 container.LoadConfiguration(section); //获取特定配置节下已命名的配置节<container name="FirstClass">下的配置信息 container.LoadConfiguration(section, "FirstClass"); IClass classInfo = container.Resolve<IClass>("ConfigClass"); classInfo.ShowInfo(); }
通过配置文件配置Unity信息需要有以下几个步骤:
1、在配置文件中<configSections> 配置节下unity注册。
2、在<configuration> 配置节下添加Unity配置信息。
3、在代码中读取配置信息,并将配置载入到UnityContainer中。
使用配置文件来配置对象信息虽然可以在部署的时候更改对象之间的依赖关系,但是当系统过于复杂,则就会导致配置文件的增大,所以我们需要将 Unity的配置信息从App.config或web.config中分离出来,但是这样的话前面的代码中调用方法就无效了,我们现在需要修改一下现有的 代码:
public static void ContainerConfigurationFromFile(string configFile) { //根据文件名获取指定config文件 var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = configFile }; //从config文件中读取配置信息 Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); var unitySection = (UnityConfigurationSection)configuration.GetSection("unity"); var container = new UnityContainer() .LoadConfiguration(unitySection, "FirstClass"); IClass classInfo = container.Resolve<IClass>("ConfigClass"); classInfo.ShowInfo(); }
由于Unity配置相对来说比较复杂,一下子难以上手,而且不像企业库的其他模块可以通过配置工具进行配置,所以p&p小组为了方便通过配 置文件进行Unity配置,已经在企业库5.0的安装包中内置了UnityConfiguration20.xsd,你可以在X:\Program Files\Microsoft Visual Studio X.0\Xml\Schemas\下找到,这样就可以在配置文件中进行Unity配置时出现只能提示了,如下图:
以上就是本文的所有内容了,主要是简单介绍一下UnityContainer的基本使用方法——如何通过代码及配置文件来实现对象之间关系,如有不对欢迎指出!
示例代码下载:点我下载