转Unity 入门

原文地址:http://www.fengfly.com/plus/view-84111-1.html是一系列

1. Unity是什么?
  Unity是patterns & practices团队开发的一个轻量级、可扩展的依赖注入容器,支持构造函数、属性和方法调用注入.具有如下的特性:
  <1>. 它提供了创建(或者装配)对象实例的机制,而这些对象实例可能还包含了其它被依赖的对象实例。
  <2>. Unity允许将预先配置的对象注入到类中,实现了inversion of control (IoC)的功能。在Unity中,支持constructor injection(构造器注入), property setter injection(属性设值注入)以及method call injection(方法注入) .
  <3>. 支持容器的体系结构。一个容器可以有子容器,允许从子容器到父容器的对象定位查询。
  <4>. 可以通过配置文件进行准备和配置容器。
  <5>. 不会影响到类的定义(属性设值注入和方法注入除外),这也是轻量级容器的一个体现。
  <6>. 支持自定义的容器扩展。
     <7>简化了对象的创建,尤其是分层的对象结构和依赖,并简化了应用程序代码。
  支持需求的抽象,这允许开发人员在运行时或者配置中指定依赖,并简化了横切关注点的管理。
  通过延迟将配置组装到容器来提高灵活性。服务定位功能允许客户代码保存或者缓存容器。这在开发人员可以持久化容器到 ASP.NET Session 或者 Application 中的 ASP.NET Web 应用程序中特别有用。

2.ObjectBuilder是什么

ObjectBuilder是一个可扩展的Application Block,同时也是Unity的基础。最普遍的描述是:ObjectBuilder是“依 赖注入的工具”,还有一种说法是“构建依赖注入容器的框架”,这些多少都有些出入。应该说ObjectBuilder是一个可配置的对象工厂。 

3.使用Unity,最基本步骤有三步。

  <1>. 建立容器;

  <2>. 将接口与类的映射注册到容器中;

  <3>. 从容器中解析出正确的对象。

实际操作,step0准备工作,为了测试,建立一个接口以及2个实现类.

public interface ILogger
    {
        
void Log(string value);
    }

public class ConsoleLogger : ILogger
    {
        
#region 成员
        
public void Log(string value)
        {
            Console.WriteLine(
string.Format("ConsoleLogger:{0}", value));
        }
        
#endregion
    }

public class NullLogger:ILogger
    {
        
#region 成员
        
public void Log(string value)
        {
            Console.WriteLine(
"NullLogger:Hey,Nothing to do!");
        }
        
#endregion
    }

  Step1. 创建容器

  在Unity中创建容器实例最简单的方法是直接使用构造函数创建,如下代码所示:

  IUnityContainer container = new UnityContainer();

  Step2. 注册接口映射

  在Unity中提供了一组Register方法供我们在容器中注册接口映射,如下代码所示:

  container.RegisterType<ILogger, ConsoleLogger>();

  Step3. 获取对象实例

  在Unity中提供了一组Resolve方法用以获取对象实例,如下代码所示:

  ILogger logger = container.Resolve<ILogger>();

  OK,就这么简单!

        public void test1()
        {
            
//Step1. 创建容器
            Microsoft.Practices.Unity.IUnityContainer container = new Microsoft.Practices.Unity.UnityContainer();

            
//Step2. 注册接口映射
            
// container.RegisterType<ILogger, ConsoleLogger>();
            container.RegisterType<ILogger, NullLogger>();

            
//Step3. 获取对象实例
            ILogger logger = container.Resolve<ILogger>();
            
            
//调用对象方法
            logger.Log("Have a look!");
            Console.ReadLine();
        }

PS:针对不同场景,可进行不同的接口映射注册....其他可保持不变

 4.Unity的使用场景主要有以下几个:

  建立类型映射

  用于单例模式

  用于依赖注入

 5.建立类型映射

类型映射,为面向对象设计的根本原则——“针对接口编程,而不是针对实现编程”、“要依赖抽象,不要依赖具体类”——在应用中的实现,提供了有力的支持。

   我们知道,Unity提供了对象的容器,那么这个容器是如何进行索引的呢?也就是说,容器内的单元是如何标识的呢?在Unity中,标识主要有两种方 式,

        一种是直接使用接口(或者基类)作为标识键,

        另一种是使用接口(或者基类)与名称的组合作为标识键。键对应的值就是具体类。

  用接口类型作为标识键.参照3中例子既是. 用基类类似..

  第二种方法:如果需要使用同样的接口(或基类)注册多个映射,可以指定名称来区分每个映射。在需要Resolve的时候,通过指定接口(或基类)与名称的组合作为标识键,就可以获取恰当类型的对象。

 如:

        public void test4()
        {
            
//Step1. 创建容器
            Microsoft.Practices.Unity.IUnityContainer container = new Microsoft.Practices.Unity.UnityContainer();

            
//Step2. 注册接口映射(指定名称来区分每个映射)区分大小写
           container.RegisterType<ILogger, ConsoleLogger>("Tom");
           container.RegisterType
<ILogger, ConsoleLogger>("jerry");

            
//Step3. 获取对象实例(结合指定名称)若用tom则报错
            ILogger logger = container.Resolve<ILogger>("Tom");
            logger.Log(
"I am tom");
            
//不同名称获取不同实例
            logger = container.Resolve<ILogger>("jerry");
            logger.Log(
"I am jerry!");

            Console.ReadLine();
        }

6.单例模式

   为了实现单例模式,我们通常的做法是,在类中定义一个方法如GetInstance,判断如果实例为null则新建一个实例,否则就返回已有实例。但是 我觉得这种做法将对象的生命周期管理与类本身耦合在了一起,与SRP原则相违背。所以我觉得遇到需要使用单例的地方,应该将生命周期管理的职责转移到对象 容器上,而我们的类依然是一个干净的类。

     将Unity应用于单例模式,主要有两种使用场景:

   (1)将类型注册为单例

  我们可以将一个接口注册为标识键,对应一个具体类。不同的是,要用于单例模式,我们需要使用一个LifetimeManager类型的参数,并指定为ContainerControlledLifetimeManager类型:

  RegisterType<TFrom, TTo>(new ContainerControlledLifetimeManager())

  (2)将已有对象注册为单例

  如果我们已经创建了一个对象,并希望使用已创建的对象作为单例,而不是由容器新创建一个对象,那么我们应该使用RegisterInstance方法。以下的代码以接口注册为例,演示了如何使用一个已有对象,为一个接口注册一个具体类,并声明为单例:



原文地址:https://www.cnblogs.com/9421/p/1641140.html