好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Unity预览

Unity预览

[IoC容器Unity]第一回:Unity预览

1.引言

高内聚,低耦合成为一个OO架构设计的一个参考标准。高内聚是一个模块或者一个类中成员跟这个模块或者类的关系尽量高,低耦合是不同模块或者不同类之间关系尽量简单。

拿咱国家举例来说,假如你是中国人。

高内聚:就是说你跟中国亲,关系好,国家会保护你。

低内聚:就是说你跟中国的关系不好,那还怎么混,改天就要批斗你,你就是个问题源。

低耦合:就是说你跟日本的关系非常正常,非常简单,这样的话,就不会被骂汉奸了。

高耦合:就是说你跟日本亲,活该被砸,被游街。

上面例子虚构的,不太贴切,但从中可以看出来高内聚和低耦合的处境是最好的。高内聚是对内部成员跟本身这个模块的关系的描述,低耦合是对成员跟外部模块之间关系的描述。对内对外也是一个相对范围,一个模块里面的小模块之间是耦合,对大模块是聚合,所以说耦合无处不在,我们都要低耦合,Untity就可以帮助我们。

2.Unity

Unity是一个IoC容器,用来实现依赖注入(Dependency Injection,DI),减少耦合的,Unity出自于伟大的微软。对依赖注入和IoC模式可以查看之前一篇文章 IoC模式 。
unity组件网址: http://unity.codeplex.com/
网址中有源码有文档有示例,大家可以下载。我是用的是2.1版本。

看看Unity能做些什么,列举部分如下:

1.Unity支持简单对象创建,特别是分层对象结构和依赖,以简化程序代码。其包含一个编译那些可能存在依赖于其他对象的对象实例机制。
2.Unity支持必要的抽象,其允许开发者在运行时或配置去指定依赖关系同时可以简单的管理横切点(AOP)。
3.Unity增加了推迟到容器组件配置的灵活性。其同样支持一个容器层次的结构。
4.Unity拥有服务定位能力,对于一个程序在许多情况下重复使用组件来分离和集中功能是非常有用的。
5.Unity允许客户端储存或缓存容器。对于在ASP.NET Web applications中开发者将容器持久化于ASP.NET中的session或application中特别有效。
6.Unity拥有拦截能力,其允许开发者通过创建并执行handlers(在方法或属性被调用到达之前)来为已存在的组件增加一个函数,并再次为返回调用结果。
7.Unity可以从标准配置系统中读取配置信息,例如:XML文件,同时使用配置文件来配置容器。
8.Unity支持开发者实现自定义容器扩展,例如:你可以实现方法来允许额外的对象构造和容器特征,例如缓存。
9.Unity允许架构师和开发者在现代化的程序中更简单的实现通用设计模式。

.....

我们项目中什么时候要使用到Unity呢,如下情况:

1.所构建的系统依赖于健全的面向对象原则,但是大量不同的代码交织在一起而难以维护。
2.构建的对象和类需要依赖其他对象或类。
3.依赖于复杂的或需要抽象的对象。
4.希望利用构造函数、方法或属性的调用注入优势。
5.希望管理对象实例的生命周期。
6.希望能够在运行时管理并改变依赖关系。
7.希望在拦截方法或属性调用的时候生成一个策略链或管道处理容器来实现横切(AOP)任务。
8.希望在Web Application中的回发操作时能够缓存或持久化依赖关系。

..............

先看看Unity容器IUnityContainer 接口的定义:

View Code

 //  Interface defining the behavior of the Unity dependency injection container. 
     public   interface   IUnityContainer : IDisposable
    {
          //  The parent of this container. 
        IUnityContainer Parent {  get  ; }

          //  Get a sequence of Microsoft.Practices.Unity.ContainerRegistration that describe
          //  the current state of the container. 
        IEnumerable<ContainerRegistration> Registrations {  get  ; }

          //  Add an extension object to the container. 
         IUnityContainer AddExtension(UnityContainerExtension extension);

          //  Run an existing object through the container and perform injection on it.         
         object  BuildUp(Type t,  object  existing,  string  name,  params   ResolverOverride[] resolverOverrides);

          //  Resolve access to a configuration interface exposed by an extension. 
         object   Configure(Type configurationInterface);

          //  Create a child container.  
         IUnityContainer CreateChildContainer();

          //  Register an instance with the container. 
        IUnityContainer RegisterInstance(Type t,  string  name,  object   instance, LifetimeManager lifetime);

          //  Register a type mapping with the container, where the created instances will
          //  use the given Microsoft.Practices.Unity.LifetimeManager. 
        IUnityContainer RegisterType(Type  from , Type to,  string  name, LifetimeManager lifetimeManager,  params   InjectionMember[] injectionMembers);
 
          //  Remove all installed extensions from this container. 
         IUnityContainer RemoveAllExtensions();

          //  Resolve an instance of the requested type with the given name from the container. 
         object  Resolve(Type t,  string  name,  params   ResolverOverride[] resolverOverrides);

          //  Return instances of all registered types requested. 
        IEnumerable< object > ResolveAll(Type t,  params   ResolverOverride[] resolverOverrides);

          //  Run an existing object through the container, and clean it up. 
         void  Teardown( object   o);
    } 

IUnityContainer 中有几个方法经常会使用到,如:RegisterInstance,RegisterType,Resolve等等。

Unity为了方便操作,专门为IUnityContainer 提供了许多的扩展方法,部分方法声明如:

View Code

 ///   <summary> 
     ///   扩展方法 v2.0.50727
      ///   </summary> 
     public   static   class   UnityContainerExtensions
    {
          public   static  IUnityContainer AddNewExtension<TExtension>( this  IUnityContainer container)  where   TExtension : UnityContainerExtension;
          public   static  T BuildUp<T>( this  IUnityContainer container, T existing,  params   ResolverOverride[] resolverOverrides);
          public   static  T BuildUp<T>( this  IUnityContainer container, T existing,  string  name,  params   ResolverOverride[] resolverOverrides);
          public   static   object  BuildUp( this  IUnityContainer container, Type t,  object  existing,  params   ResolverOverride[] resolverOverrides);
          public   static  TConfigurator Configure<TConfigurator>( this  IUnityContainer container)  where   TConfigurator : IUnityContainerExtensionConfigurator;
          public   static   bool  IsRegistered<T>( this   IUnityContainer container);
          public   static   bool  IsRegistered<T>( this  IUnityContainer container,  string   nameToCheck);
          public   static   bool  IsRegistered( this   IUnityContainer container, Type typeToCheck);
          public   static   bool  IsRegistered( this  IUnityContainer container, Type typeToCheck,  string   nameToCheck);
          public   static  IUnityContainer RegisterInstance<TInterface>( this   IUnityContainer container, TInterface instance);
          public   static  IUnityContainer RegisterInstance<TInterface>( this  IUnityContainer container,  string   name, TInterface instance);
          public   static  IUnityContainer RegisterInstance<TInterface>( this   IUnityContainer container, TInterface instance, LifetimeManager lifetimeManager);
          public   static  IUnityContainer RegisterInstance( this  IUnityContainer container, Type t,  object   instance);
          public   static  IUnityContainer RegisterInstance<TInterface>( this  IUnityContainer container,  string   name, TInterface instance, LifetimeManager lifetimeManager);
          public   static  IUnityContainer RegisterInstance( this  IUnityContainer container, Type t,  object   instance, LifetimeManager lifetimeManager);
          public   static  IUnityContainer RegisterInstance( this  IUnityContainer container, Type t,  string  name,  object   instance);
          public   static  IUnityContainer RegisterType<T>( this  IUnityContainer container,  params   InjectionMember[] injectionMembers);
          public   static  IUnityContainer RegisterType<TFrom, TTo>( this  IUnityContainer container,  params  InjectionMember[] injectionMembers)  where   TTo : TFrom;
          public   static  IUnityContainer RegisterType<T>( this  IUnityContainer container, LifetimeManager lifetimeManager,  params   InjectionMember[] injectionMembers);
          public   static  IUnityContainer RegisterType<TFrom, TTo>( this  IUnityContainer container, LifetimeManager lifetimeManager,  params  InjectionMember[] injectionMembers)  where   TTo : TFrom;
          public   static  IUnityContainer RegisterType<TFrom, TTo>( this  IUnityContainer container,  string  name,  params  InjectionMember[] injectionMembers)  where   TTo : TFrom;
          public   static  IUnityContainer RegisterType<T>( this  IUnityContainer container,  string  name,  params   InjectionMember[] injectionMembers);
          public   static  IUnityContainer RegisterType( this  IUnityContainer container, Type t,  params   InjectionMember[] injectionMembers);
          public   static  IUnityContainer RegisterType<T>( this  IUnityContainer container,  string  name, LifetimeManager lifetimeManager,  params   InjectionMember[] injectionMembers);
          public   static  IUnityContainer RegisterType<TFrom, TTo>( this  IUnityContainer container,  string  name, LifetimeManager lifetimeManager,  params  InjectionMember[] injectionMembers)  where   TTo : TFrom;
          public   static  IUnityContainer RegisterType( this  IUnityContainer container, Type t, LifetimeManager lifetimeManager,  params   InjectionMember[] injectionMembers);
          public   static  IUnityContainer RegisterType( this  IUnityContainer container, Type t,  string  name,  params   InjectionMember[] injectionMembers);
          public   static  IUnityContainer RegisterType( this  IUnityContainer container, Type  from , Type to,  params   InjectionMember[] injectionMembers);
          public   static  IUnityContainer RegisterType( this  IUnityContainer container, Type t,  string  name, LifetimeManager lifetimeManager,  params   InjectionMember[] injectionMembers);
          public   static  IUnityContainer RegisterType( this  IUnityContainer container, Type  from , Type to, LifetimeManager lifetimeManager,  params   InjectionMember[] injectionMembers);
          public   static  IUnityContainer RegisterType( this  IUnityContainer container, Type  from , Type to,  string  name,  params   InjectionMember[] injectionMembers);
          public   static  T Resolve<T>( this  IUnityContainer container,  params   ResolverOverride[] overrides);
          public   static  T Resolve<T>( this  IUnityContainer container,  string  name,  params   ResolverOverride[] overrides);
          public   static   object  Resolve( this  IUnityContainer container, Type t,  params   ResolverOverride[] overrides);
          public   static  IEnumerable<T> ResolveAll<T>( this  IUnityContainer container,  params   ResolverOverride[] resolverOverrides);

          public   static  IUnityContainer LoadConfiguration( this   IUnityContainer container);
          public   static  IUnityContainer LoadConfiguration( this  IUnityContainer container,  string   containerName);
          public   static  IUnityContainer LoadConfiguration( this   IUnityContainer container, UnityConfigurationSection section);
          public   static  IUnityContainer LoadConfiguration( this  IUnityContainer container, UnityConfigurationSection section,  string   containerName);
    } 

下面来个简单的例子,现在项目中添加Microsoft.Practices.Unity.dll和Microsoft.Practices.Unity.Configuration.dll的引用,准备几个类,如下:

View Code

 ///   <summary> 
     ///   班级接口
      ///   </summary> 
     public   interface   IClass
    {
          string  ClassName {  get ;  set  ; }

          void   ShowInfo();
    }
      ///   <summary> 
     ///   计科班
      ///   </summary> 
     public   class   CbClass : IClass
    {
          public   string  ClassName {  get ;  set  ; }

          public   void   ShowInfo()
        {
            Console.WriteLine(  "  计科班:{0}  "  , ClassName);
        }
    }
      ///   <summary> 
     ///   电商班
      ///   </summary> 
     public   class   EcClass : IClass
    {
          public   string  ClassName {  get ;  set  ; }

          public   void   ShowInfo()
        {
            Console.WriteLine(  "  电商班:{0}  "  , ClassName);
        }
    } 

用编程方式实现注入:

View Code

 public   static   void   ContainerCodeTest1()
        {
            IUnityContainer container  =  new   UnityContainer();
            
              //  默认注册(无命名),如果后面还有默认注册会覆盖前面的 
            container.RegisterType<IClass, CbClass> ();
          
              //  命名注册 
            container.RegisterType<IClass, EcClass>( "  ec  "  );

              //  解析默认对象 
            IClass cbClass = container.Resolve<IClass> ();
            cbClass.ShowInfo();

              //  指定命名解析对象 
            IClass ecClass = container.Resolve<IClass>( "  ec  "  );           
            ecClass.ShowInfo();

              //  获取容器中所有IClass的注册的已命名对象 
            IEnumerable<IClass> classList = container.ResolveAll<IClass> ();
              foreach  ( var  item  in   classList)
            {
                item.ShowInfo();
            }
        } 

配置文件方式:

View Code

 <?  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"  > 
     <!--  定义类型别名  --> 
     <  aliases  > 
       <  add   alias  ="IClass"   type  ="ConsoleApplication1.UnityDemo.IClass,ConsoleApplication1"   /> 
       <  add   alias  ="CbClass"   type  ="ConsoleApplication1.UnityDemo.CbClass,ConsoleApplication1"   /> 
       <  add   alias  ="EcClass"   type  ="ConsoleApplication1.UnityDemo.EcClass,ConsoleApplication1"   /> 
     </  aliases  > 
     <!--  容器  --> 
     <  container   name  ="FirstClass"  > 
       <!--  映射关系  --> 
       <  register   type  ="IClass"    mapTo  ="CbClass"  ></  register  > 
       <  register   type  ="IClass"   name  ="ConfigEc"   mapTo  ="EcClass"  ></  register  > 
     </  container  > 
   </  unity  > 
 </  configuration  > 

View Code

  public   static   void   ContainerCodeTest1()
        {
            IUnityContainer container  =  new   UnityContainer();
            
              //  默认注册(无命名),如果后面还有默认注册会覆盖前面的 
            container.RegisterType<IClass, CbClass> ();
          
              //  命名注册 
            container.RegisterType<IClass, EcClass>( "  ec  "  );

              //  解析默认对象 
            IClass cbClass = container.Resolve<IClass> ();
            cbClass.ShowInfo();

              //  指定命名解析对象 
            IClass ecClass = container.Resolve<IClass>( "  ec  "  );           
            ecClass.ShowInfo();

              //  获取容器中所有IClass的注册的已命名对象 
            IEnumerable<IClass> classList = container.ResolveAll<IClass> ();
              foreach  ( var  item  in   classList)
            {
                item.ShowInfo();
            }
        } 

效果跟代码方式一样

Unity使用方式基本分为三步:

声明容器IUnityContainer Register注册类型 Resolve解析类型对象 3.小结

看到IUnityContainer接口声明还是比较简单的,主要用到的方法也不多,另外提供了扩展方法,看起来代码挺多,都是一些方法重载,不要对Unity组建感到恐惧,我们只是简单的使用它,主要是使用IUnityContainer。

作者: Qlin  
出处: http://www.cnblogs.com/qqlin/  
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

分类:  架构设计

标签:  IoC ,  Unity

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于Unity预览的详细内容...

  阅读:50次