到公司接触的第一个项目就遇到了IOC框架的使用。项目经理决定使用微软的Unity Application Block,因此写了这个简单的例子说明一下最基本的Unity应用。
因为理论和语言水平有限,就不说那么多的道道了。就用最土的文字表明一下我对IOC的理解。
以往的开发中,为了实现应用程序的可装配我们通常是使用工厂模式或者是类似的模式。但是这样的缺点是不管怎么样还是有一些依赖。但是在IOC中,针对某个应用模块调用的抽象类型的具体实现类型不在编码时指定,而是在运行期通过读取配置文件或者是其他运行时可获得的定义来动态的生成对象并传递给调用者(专业术语好像是注入)。
下面是我写的一个小例子:
App.config文件配置
- <?xml version="1.0" encoding="utf-8" ?>
- <configuration>
- <configSections>
- <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
- Microsoft.Practices.Unity.Configuration"/>
- </configSections>
- <unity>
- <typeAliases>
- <typeAlias alias="SayHello" type="UnityDemo.IHello,UnityDemo" />
- <typeAlias alias="SayHelloA" type="UnityDemo.ClassA,UnityDemo" />
- <typeAlias alias="SayHelloB" type="UnityDemo.ClassB,UnityDemo" />
- </typeAliases>
- <containers>
- <container name="Hello">
- <types>
- <type type="SayHello" mapTo="SayHelloB">
- <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
- Microsoft.Practices.Unity.Configuration">
- </typeConfig>
- </type>
- </types>
- </container>
- </containers>
- </unity>
- </configuration>
测试代码:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- //必须的引用
- using System.Configuration;
- using Microsoft.Practices.Unity;
- using Microsoft.Practices.Unity.Configuration;
- namespace UnityDemo
- {
- class Program
- {
- static void Main(string[] args)
- {
- ///获取容器
- IUnityContainer contaner = new UnityContainer();
- ///获取配置
- UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
- ///使用指定的配置节对容器进行配置初始化
- section.Containers["Hello"].Configure(contaner);
- ///通过容器获取指定的类型的实时绑定的类型
- IHello hello = contaner.Resolve<IHello>();
- ///调用方法
- hello.SayHello();
- Console.ReadKey();
- }
- }
- /// <summary>
- /// 实际调用的接口
- /// </summary>
- interface IHello
- {
- void SayHello();
- }
- /// <summary>
- /// 实现A
- /// </summary>
- class ClassA : IHello
- {
- public void SayHello()
- {
- Console.Write(this.GetType().Name);
- }
- }
- /// <summary>
- /// 实现B
- /// </summary>
- class ClassB : IHello
- {
- public void SayHello()
- {
- Console.Write(this.GetType().Name);
- }
- }
- }
程序运行输出的结果是:
ClassB
如果改变了配置文件里面mapTo的配置为SayHelloA,那么将会输出:
ClassA
这里需要特别注意的是配置文件。可以说,配置文件是Unity Application Block的核心。下面是Unity Application Block的配置XML的Unity Configuration Schematic定义:
具体的定义这里只说最简单的几个:
- <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
- Microsoft.Practices.Unity.Configuration"/>
该节点是使用Unity Application Block必须的。
- <unity>
- <typeAliases>
- <typeAlias alias="SayHello" type="UnityDemo.IHello,UnityDemo" />
- <typeAlias alias="SayHelloA" type="UnityDemo.ClassA,UnityDemo" />
- <typeAlias alias="SayHelloB" type="UnityDemo.ClassB,UnityDemo" />
- </typeAliases>
- <containers>
- <container name="Hello">
- <types>
- <type type="SayHello" mapTo="SayHelloB">
- <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
- Microsoft.Practices.Unity.Configuration">
- </typeConfig>
- </type>
- </types>
- </container>
- </containers>
- </unity>
该节点是具体的对Unity Application Block的配置信息。各个分节点说明如下:
typeAlias:为指定的类型添加别名,因为直接使用类型说明字符串来进行下面的配置将会很复杂而且容易出错。alias指定别名,type指定该别名对应的实际类型。
container:指定使用类型和具体实现类型之间的映射。看到配置文件应该就可以明白这里的mapTo的含义了。
如果需要对这里的配置做更深入的分析请参考我上传的文档 Unity Application Block 1.2