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,理解浅薄,请各位朋友见谅指正。

 

该睡了,晚安。

你可能感兴趣的:(application)