Unity Application 学习
Unity Application 学习笔记1 --初识
上一篇文章中间简要的写了一个 关于Autofac 东西。这两天看了一下关于Unity Application 的一些运用。
类似上一篇,写了几个相同的例子。
最开始时使用编码注入的方式。
代码如下:
1 class Program
2 {
3 static void Main( string [] args)
4 {
5 Program p = new Program();
6 // p.Test3();
7 p.Test4();
8
9 Console.Read();
10 }
11
12 public void Test1()
13 {
14 UnityContainer container = new UnityContainer();
15 container.RegisterType<ILog,PrintLoger> ();
16 container.RegisterInstance(Console.Out); // container.RegisterInstance<TextWriter>(Console.Out);
17
18 container.Resolve<ILog>().Create( " this is test1 " );
19 // 将组件PrinterLoger注册到Ilog服务上,同时将Console.Out实例注册到TextWriter上
20 // 请求Ilog服务的时候,会构造PrinterLoger组件的一个实例,使用参数Console.Out.构造成功。正常输出
21 container.Dispose();
22 }
23
24 public void Test2()
25 {
26 UnityContainer container = new UnityContainer();
27 container.RegisterType<PrintLoger> ();
28 container.RegisterInstance(Console.Out);
29 container.Resolve<PrintLoger>().Create( " this is test2 " );
30 container.Dispose();
31
32 // 可正常输出。理解应该和autofac相同,我们将PrinterLoger 注册到容器内
33 // 同时将组件的实例注册到TextWriter上
34 // Resolve PrinterLoger时,会构造请求该服务的组件的一个实例,调用其构造函数,传入Console.out参数,正常运行输出
35 }
36
37 public void Test3()
38 {
39 UnityContainer container = new UnityContainer();
40 container.RegisterType<Person> ();
41 Person p= container.Resolve<Person> ();
42 // 本例子只是为了说明一个类可以注册到自己身上,并且Reslove出来
43 container.Dispose();
44 }
45
46 public void Test4()
47 {
48 using (UnityContainer container= new UnityContainer())
49 {
50 container.RegisterInstance<TextWriter> (Console.Out);
51 container.RegisterType<ILog, PrintLoger> ();
52 // RegisterType可以 有两个泛型参数,From,To,其中,To是继承与From的
53 // 其实也就是将To组件注册到From服务上
54 // 当请求Reslove一个PrintLoger实例的时候,这个地方貌似不同于AutoFac的处理
55 // 能够使用该类去构造出一个实例(但前提是参数TextWriter可以Reslove出来)
56
57 container.Resolve<PrintLoger>().Create( " this is test4 " ); // 此处跟autofac 不同,不注册PrintLoger 也可以Resolve出来 todo cjt!!!!!
58 }
59 }
60
61
62 }
类和接口
public interface ILog
{
void Create( string log, params object [] paramters);
}
public class PrintLoger : ILog
{
protected TextWriter TW { get ; set ; }
public PrintLoger(TextWriter tw)
{
this .TW = tw;
}
public void Create( string log, params object [] paramters)
{
if (log == null )
return ;
string Log = string .Format(log, paramters);
TW.WriteLine(Log);
}
}
public class Person
{
public string ID { get ; set ; }
public string Name { get ; set ; }
}
可以看出来,同Autofac的差别主要就在于Test4 上。在Autofac中,如果没有注册PrintLoger时,是无法Reslove 出一个实例的,而Unity Application 可以。
其他的,基本可以用相同的思维去理解。Register 将服务和组件 Map到一起(或者直接指定服务使用的组件实例)。
另外,Unity Application 还可以通过配置文件的方式,进行注入。
1 class Program
2 {
3 static void Main( string [] args)
4 {
5 Program p = new Program();
6 // p.Test1();
7 p.Test2();
8 p.Test3();
9
10 Console.ReadKey();
11
12 }
13
14 public void Test1()
15 {
16 IUnityContainer container = new UnityContainer().AddNewExtension<Interception> ();
17 UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection( " unity " );
18 // 使用名称为Hello的Container,将文件中的配置读取初始化到Container中
19 section.Configure(container, " Hello " );
20 IHello hello = container.Resolve<IHello> ();
21 // 由于在Hello Container中,我们将IHello map 到 HelloB ,其将使用HelloB 进行构造实例
22 // 实际上,这个地方运行时,是会报错的,Container会无法Reslove Ilog,我们并没有在该Container中队Ilog进行映射
23 hello.SayHello();
24 container.Dispose();
25 }
26
27 public void Test2()
28 {
29 IUnityContainer container = new UnityContainer();
30 UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection( " unity " );
31 // 该例子比较好理解,我们在配置文件中的Log Container 中配置了Ilog map 到 ClassPrintLog中
32 // 请求ILog服务的时候,将会构造PrintLog实例,PrintLog是无参构造,Reslove成功
33 section.Configure(container, " Log " );
34 container.Resolve<ILog>().Create( " this is ilog " );
35 container.Dispose();
36 }
37
38 public void Test3()
39 {
40 IUnityContainer container = new UnityContainer();
41 UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection( " unity " );
42 // 在该节点的Container中,我们 将IHello map 到HelloA 将ILog map 到 PrintLog
43 // 当请求Reslove IHello 时, 将会构造HelloA实例,然而发现HelloA 需要参数 ILog ,Container继续Reslove Ilog ,将会得到PrintLog实例
44 // 如此,完成IHello hello=new HelloA(new PrintLog() ) 的构造
45 // Test1中和本例中都有一个不明白的地方,Unity 为什么会选中 含有参数的构造函数,而不使用无参的构造函数呢? Unity是如何选择构造函数的呢?
46 section.Configure(container, " SayHelloLog " );
47 container.Resolve<IHello> ().SayHello();
48 container.Dispose();
49 }
50
51 }
配置文件
配置文件中 会在<typeAliases></typeAliases> 节点 为 需要注册的类增加别名。注意Type 是由 名空间.类名,程序集名 两部分构成的。
然后可以配置若干个Container,依据名字对其区分。
1 <? xml version="1.0" ?> 2 < configuration > 3 < configSections > 4 < section name ="unity" type ="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration" /> 5 </ configSections > 6 < unity > 7 < typeAliases > 8 < typeAlias alias ="SayHello" type ="ConAppUnityHelloWord.IHello,ConAppUnityHelloWord" ></ typeAlias > 9 < typeAlias alias ="SayHelloA" type ="ConAppUnityHelloWord.ClassA,ConAppUnityHelloWord" ></ typeAlias > 10 < typeAlias alias ="SayHelloB" type ="ConAppUnityHelloWord.ClassB,ConAppUnityHelloWord" ></ typeAlias > 11 < typeAlias alias ="Log" type ="ConAppUnityHelloWord.ILog,ConAppUnityHelloWord" ></ typeAlias > 12 < typeAlias alias ="PrintLog" type ="ConAppUnityHelloWord.PrintLog,ConAppUnityHelloWord" ></ typeAlias > 13 </ typeAliases > 14 < containers > 15 < container name ="Hello" > 16 < types > 17 < type type ="SayHello" mapTo ="SayHelloB" > 18 <!-- <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, 19 Microsoft.Practices.Unity.Configuration"></typeConfig> --> 20 </ type > 21 </ types > 22 </ container > 23 < container name ="Log" > 24 < types > 25 < type type ="Log" mapTo ="PrintLog" ></ type > 26 </ types > 27 </ container > 28 < container name ="SayHelloLog" > 29 < types > 30 < type type ="SayHello" mapTo ="SayHelloA" ></ type > 31 < type type ="Log" mapTo ="PrintLog" ></ type > 32 </ types > 33 </ container > 34 </ containers > 35 </ unity > 36 < startup >< supportedRuntime version ="v4.0" sku =".NETFramework,Version=v4.0" /></ startup ></ configuration >
类和接口
View Code
1 interface IHello
2 {
3
4 void SayHello();
5 }
6
7 public class ClassB:IHello
8 {
9 public void SayHello()
10 {
11 Console.WriteLine( this .GetType().Name);
12 }
13
14 public ClassB()
15 {
16
17 }
18
19 public ClassB(ILog log)
20 {
21 log.Create( " say hellob " );
22 }
23 }
24
25
26 public class ClassA : IHello
27 {
28 public void SayHello()
29 {
30 Console.WriteLine( this .GetType().Name);
31 }
32
33 public ClassA()
34 {
35
36 }
37
38 public ClassA(ILog log)
39 {
40 log.Create( " say helloa " );
41 }
42 }
43
44 public interface ILog
45 {
46 void Create( string log);
47 }
48
49 public class PrintLog : ILog
50 {
51 public void Create( string log)
52 {
53 Console.WriteLine( " this is log " + log);
54 }
55 }
对于 使用配置文件进行注入 理解上和使用编码方式差不多。都是将 组件映射到服务上,然后Container读取这些映射,Reslove出组件的实例。
不过这里还有一些疑问,等过些阵子明了了,再来解决。如果有路过的朋友能指点一二,将不胜感激。
1. Autofac中如果不注册 PrintLog 就无法ReslovePrintLog ,而Unity Application 中却可以,默认构造出该类的一个实例。这个差别是确实这样?还是代码有问题?。如果确实有这个差别,那么 二者存在这样差异在框架上又是什么原因。
2.如何通过Unity 的配置文件,注册 一个实例呢?就像RegisterInstance一样。疑惑中。
3. 还需要看一下Unity对 对象生命周期的管理。
初学IOC,理解浅薄,请各位朋友见谅指正。
该睡了,晚安。
分类: Unity Application
标签: IOC , Unity Application
作者: Leo_wl
出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于Unity Application 学习的详细内容...