zoukankan      html  css  js  c++  java
  • IOC注入框架——Unity初步

    Unity 应用程序块(Unity)是一个轻量级、可扩展的依赖注入容器,支持构造函数、属性和方法调用注入。它有下列优点:
    1、简化了对象的创建,尤其是分层的对象结构和依赖,并简化了应用程序代码。
    2、支持需求的抽象,这允许开发人员在运行时或者配置中指定依赖,并简化了横切关注点的管理。
    3、通过延迟将配置组装到容器来提高灵活性。
    4、服务定位功能允许客户代码保存或者缓存容器。这在开发人员可以持久化容器到 ASP.NET Session 或者 Application 中的 ASP.NET Web 应用程序中特别有用。

    依赖注入:这是 Ioc 模式的一种特殊情况,是一种基于改变对象的行为而不改变类的内部的接口编程技术。开发人员编写实现接口的类代码,并基于接口或者对象类型使用容器注入依赖的对象实例到类中。用于注入对象实例的技术是接口注入、构造函数注入、属性(设置器)注入和方法调用注入。

    准备工作:
    1、安装Unity Application Block 1.1.msi
    2、创建新网站
    3、添加Microsoft.Practices.Unity.Configuration.dll、Microsoft.Practices.Unity.dll、Microsoft.Practices.ObjectBuilder2.dll三个文件的引用
    4、创建一个新的类文件(.cs),并导入命名空间
        using Microsoft.Practices.Unity;
        using Microsoft.Practices.Unity.Configuration;
    5、在此类文件中建立如下几个类
    //抽象类,播放器
    public abstract class Player
    {
        public abstract string Play(); //播放功能
    }

    //MP3播放器
    public class MP3Player : Player
    {
         public override string Play()
        {
            return "this is MP3Player";
        }
    }

    //CD播放器
    public class CDPlayer : Player
    {
         public override string Play()
        {
            return "this is CDPlayer";
        }
    }

    //DVD播放器
    public class DVDPlayer : Player
    {
        public override string Play()
        {
            return "this is DVDPlayer";
        }
    }

    一、创建容器
        IUnityContainer container = new UnityContainer();
        该容器的作是用管理抽象类型与对应具体类型的工具,所以它是我们Unity中实现依赖注入的必备对象
       
    二、在容器中注册抽象类型 与具体类型的映射关系。有两种注册方式。
        1. RegisterType:在容器中注册“接口”( 包括 Interface 和 Base Class ) 到“具体类”的映射。
            container.RegisterType<IPlayer, Mp3Player>();//注册IPlay接口映射为Mp3Player类
           
            一个接口可能会映射多个具体类,可以为每个映射指定Name,如:
            container.RegisterType<IPlayer, Mp3Player>("myMp3Player1");
            container.RegisterType<IPlayer, CDPlayer>("myCDPlayer1");
           
            RegisterType有以下几个重载方法:
            RegisterType<TFrom, TTo>( )
            RegisterType<TFrom, TTo>(LifetimeManager lifetime)
            RegisterType<TFrom, TTo>(String name)
            RegisterType<TFrom, TTo>(String name, LifetimeManager lifetime)
            RegisterType<T>(LifetimeManager lifetime)
            RegisterType<T>(String name, LifetimeManager lifetime)

        2. RegisterInstance:在容器中注册“接口”( 包括 Interface 和 Base Class ) 到“实例”的映射。
            Mp3Player mp3Player = new Mp3Player();
            container.RegisterInstance<IPlayer>(mp3Player);//注册IPlayer接口映射为mp3Player实例
           
            同样的也可以为该映射指定Name,如:
            container.RegisterInstance<IPlayer>("myMp3Player", mp3Player);
           
            RegisterInstance有以下几个重载方法:
            RegisterInstance<TInterface>(TInterface instance)
            RegisterInstance<TInterface>(TInterface instance, LifetimeManager lifetime)
            RegisterInstance<TInterface>(String name, TInterface instance)
            RegisterInstance<TInterface>(String name, TInterface instance, LifetimeManager lifetime)

    三、根据容器中注册的映射关系,来动态取得对象实例
        IUnityContainer container = new UnityContainer();
        container.RegisterType<IPlayer, Mp3Player>();
        IPlayer player = container.Resolve<IPlayer>();//通过Resolve方法获取IPlayer接口所映射的Mp3Player的实例。
       
        如果IPlayer接口注册两个映射类:Mp3Player和CDPlayer。通过Resolve方法获取到的这个player对象将获取的是最后注册的具体类型的对象。
        IUnityContainer container = new UnityContainer();
        container.RegisterType<IPlayer, Mp3Player>();
        container.RegisterType<IPlayer, CDPlayer>();
        IPlayer player = container.Resolve<IPlayer>();
        player.Play(); //此时调用的方法是CDPlayer对象的Play方法。
       
        Unity中当遇到一个接口映射到多个具体类情况时,Resolve时候使用最后注册的映射。如果获得指定的具体类的对象,应当在容器中注册的时候为每个注册起个名子,并在解析(Resolve)是指定要解析的名子。
       
        IUnityContainer container = new UnityContainer();
        container.RegisterType<IPlayer, Mp3Player>("myMp3Player1");
        container.RegisterType<IPlayer, CDPlayer>("myCDPlayer1");
        IPlayer player = container.Resolve<IPlayer>("myMp3Player1");
        palyer.Play(); ////此时调用的方法是MP3Player对象的Play方法。
       
        可以看出Resolve方法可以通过指定Name( 这个Name值对应着RegisterType时指定的Name值 ),通过这种方式可以获取到指定的对象实例。所以当一个接口映射到多个具体类时,还是很有必要为这些映射指定Name。
        注意:RegisterType<TFrom,TTO>(string name)和Resolve<T>(string name)方法中的name值为大小写敏感的。
       
        Resolve的重载方法:
        Resolve<T>( )
        Resolve<T>(string name)
        Resolve(Type t)
        Resolve(Type t, string name)

    四、获取所有对象实例
        可以通过ResolveAll方法来获取指定接口的所有对象实例:
        ResolveAll方法返回的IEnumerable类型的对象,可以使用foreach进行迭代
       
        IUnityContainer container = new UnityContainer();
        container.RegisterType<IPlayer, Mp3Player>("myMP3Player");
        container.RegisterType<IPlayer, CDPlayer>("myCDPlayer");
        container.RegisterType<IPlayer, DVDPlayer>();

        IEnumerable<IPlayer> players = container.ResolveAll<IPlayer>();

        foreach (IPlayer player in players)
        {
            player.Play();
        }
       
        ResolveAll有以下两个重载方法:
        ResolveAll<T>( )
        ResolveAll(Type t)

  • 相关阅读:
    BZOJ.1468.Tree(点分治)
    BZOJ.1935.[SHOI2007]Tree园丁的烦恼(CDQ分治 三维偏序)
    BZOJ.4319.[cerc2008]Suffix reconstruction(后缀数组 构造 贪心)
    BZOJ.3262.陌上花开([模板]CDQ分治 三维偏序)
    洛谷.3374.[模板]树状数组1(CDQ分治)
    BZOJ.4566.[HAOI2016]找相同字符(后缀数组 单调栈)
    POJ.3145.Common Substrings(后缀数组 倍增 单调栈)
    POJ.2774.Long Long Message/SPOJ.1811.LCS(后缀数组 倍增)
    POJ.1743.Musical Theme(后缀数组 倍增 二分 / 后缀自动机)
    UOJ.35.[模板]后缀排序(后缀数组 倍增)
  • 原文地址:https://www.cnblogs.com/zpc870921/p/2742812.html
Copyright © 2011-2022 走看看