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)

  • 相关阅读:
    Aurora 数据库支持多达五个跨区域只读副本
    Amazon RDS 的 Oracle 只读副本
    Amazon EC2 密钥对
    DynamoDB 读取请求单位和写入请求单位
    使用 EBS 优化的实例或 10 Gb 网络实例
    启动 LAMP 堆栈 Web 应用程序
    AWS 中的错误重试和指数退避 Error Retries and Exponential Backoff in AWS
    使用 Amazon S3 阻止公有访问
    路由表 Router Table
    使用MySQLAdmin工具查看QPS
  • 原文地址:https://www.cnblogs.com/zpc870921/p/2742812.html
Copyright © 2011-2022 走看看