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://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于Unity Application 学习的详细内容...