[AaronYang风格]微软Unity2.X系统学习笔记,记录

读者约定:

Unity我直接简写U了


Unity Dependency Injection(DI)

欢迎学习Unity,通过学完下面的几个流程的引导,你应该就可以很顺利的应用Unity到你的项目中去了:

 

  1. Unity是什么
  2. Unity 能做什么
  3. 什么时候使用Unity
  4. Unity的Release版本的介绍
  5. 配置Unity
  6. 在项目中使用Unity
  7. Unity的设计
  8. 拓展和修改Unity
  9. 部署和操作
  10. Unity QuickStarts项目(这个教程都是在制作QuickStarts项目,给你讲解Unity,应用程序中最常见的操作)



1.Unity是什么?

一个轻量级,可拓展的DI容器:支持

  • interception(拦截)
  • constructor injection,(构造器注入)
  • property injection(属性注入)
  • method call injection(方法调用注入)

可以帮你降低项目中模块之间的耦合性,算了。。就是一句话,让你的项目高内聚,低耦合,简化实现的设计,简化测试,简化项目管理,原文

(You can use Unity in a variety of different ways to help decouple the components of your applications, to maximize coherence in
components, and to simplify design, implementation, testing, and administration of these applications)

对于基于微软.net framework的程序Unity都是通用的。它提供了很多注入机制,包括 注册类型映射,对象实例的方法,Resolve对象,管理对象生命周期,可以在构造函数,方法注入,这样就可以解决对象属性赋值的问题

此外,Unity可拓展,你可以拓展来改变容器的行为,或者添加一个新功能,比如说unity的”拦截“特色(就是被拓展实现的,通过给对象添加一个策略完成的)。

下面几个先大致缩略介绍一下:

  1. Unity 能做什么 
            能帮助你理解Unity能干什么,它拥有的一些概念和特点,也提供一个使用Unity写的简短的例子
  2. 什么时候使用Unity
           通过了解,你可以知道Unity是否满足你的需要,介绍了Unity的优点,同时也提供了几个其他的技术方案给你考虑.但也介绍了Unity的局限性,这个可能会影响你的决定是否使用Untiy.
  3. Unity的Release版本的介绍
           讲了一下 ,这次版本的变化,因为有的人使用老版本,所以说了一些迁移注意事项和方法
  4. 配置Unity
           本章讲解:如何使用类型注册,映射,扩展,还有其他的需要的来填充容器。
  5. 在项目中使用Unity
           感觉重点了,教你在你的项目中如何使用Unity,向项目中添加Unity,怎样Resolve对象,怎样使用Unity的其他功能
  6. Unity的设计
           讲了一下 ,Unity背后的设计和依据
  7. 拓展和修改Unity
           讲了一下 ,如何拓展Unity,如何修改Unity
  8. 部署和操作
           讲了一下 ,如何部署和升级Unity程序集,如何使用Unity暴露的仪器

2.Unity能做什么?

通过DI和控制反转的机制,你可以生成和装配自定义类的实例,独立对象实例和设置。以下几点你可以使用的Unity提供的特点:

------------------------------------------------------------------------------------------------------------------------------------------------

  • Unity可以创建的对象的类型 (The Types of Objects Unity Can Create)
  • 注册已经存在的类型和对象的实例(Registering Existing Types and Object Instances)
  • 管理对象生命周期(Managing the Lifetime of Objects)
  • 指定值用于注入(Specifying Values for Injection)
  • 填充和注入数组,包括泛型数组(Populating and Injecting Arrays, Including Generic Arrays)
  • 拦截对象的调用(Intercepting Calls to Objects)

------------------------------------------------------------------------------------------------------------------------------------------------

2.1  Unity可以创建的对象的类型

在没有注册注册容器类型映射的前提下,你可以使用Unity产生任何拥有public构造函数的(换句话说就是,可以使用new操作符创建的对象)对象。当你调用了Resolve方法并指定了一个未注册的类型实例作为参数,容器只是简单地调用了构造函数并返回一个结果给你。

Unity暴露了一个RegisterType方法(注册类型和映射的容器)。也提供了一个Resolve方法(让容器为你指定的类型生成一个指定类型的对象)。Resolve方法创建的对象的生命周期等同于你在方法中指定的参数一样。如果你不指定参数,容器每次调用Resolve都会创建一个新的实例。(如果你知道设计模式中的单例模式,应该就很容易理解什么意思了),更多信息请查看 Registering Types and Type Mappings(暂时还没写)

2.2注册已经存在的类型和对象的实例

Unity暴露了一个RegisterInstance的方法,你可以在容器中注册一个已经存在的类型了。当你调用Resolve方法时候,容器在生命周期内就会返回那个已经存在的实例。如果你没有为生命周期指定一个值,那么它的实例就会有个容器控制的声明周期,这就意味着它是一个单例了。更多信息请查看Creating Instance Registrations(暂时还没写)

2.3管理对象声明周期

Unity允许你选择它创建的对象的生命周期。默认情况下,你Resolve一下,就会创建一个新的对象。但是,你可以在Resolve实例的时候,可以使用生命周期管理者去指定一个不一样的生命周期。举个例子,你可以让Unity为你维护一个单例(如果没有对象,就会创建一个对象,如果存在对象,那就返回那个对象,这就是单例)。当然还有其他的生命周期管理方式。举个例子,你可以使用生命周期管理者去维护对象弱引用,是为了创建对象后使用你也可以随时去释放它,有时候单例的时候可能被多个线程同时使用,使用Unity可以保证每一个分开的线程都可以使用同一个单例(对象)。(真心看不懂最后一句话,如果不懂,你可以看看单例模式~)

原文:

For example, you can use a lifetime manager that holds only a weak reference to objects so that the creating process can dispose them, or a lifetime manager that maintains a separate single instance of an object on each separate thread that resolves it.

当你注册一个类型,类型映射,他们的生命周期可以由你控制生命周期管理器管理,还有,你在设计时就可以对已经存在的对象进行配置。可以参考 Specifying Types in the Configuration File   或者还有个选择,可以在运行时候向容器注册,然后指定生命周期方式。可以参考Registering Types and Type Mappings 或者 Creating Instance Registrations

2.4 为构造函数,方法和属性 的注入 配置类型

Unity允许你使用 构造器注入,方法注入,属性注入的方式 生成和装配完成所有依赖对象的实例和设置。更多信息:Specifying Values for Injection

Registering Injected Parameter and Property Values

2.4.1 构造函数注入的例子
下面是个构造函数注入的例子。如果在Unity容器中,有个类定义了一个或者多个依赖于其他类的构造函数,当你使用Resolve初始化的时候,Untiy会自动创建一个依赖对象实例,并向它的构造函数中赋值那个对象。看下面的代码,演示了一个名叫CustomerService的类中有一个依赖类叫LoggingService

public class CustomerService
{
public CustomerService(LoggingService myServiceInstance)
{
// work with the dependent instance
myServiceInstance.WriteToLog("SomeValue");
}

运行时候, 开发者可以通过Resolve方法创建CustomerService实例,这种方式,同时也会在CustomerServic作用域中创建一个LoggingService实例,就相当于注入了一个实体类(Concrete class)LoggingService的实例

IUnityContainer uContainer = new UnityContainer();
CustomerService myInstance = uContainer.Resolve<CustomerService>();

2.4.2 属性注入的例子

除了构造函数注入,更早一点,Untiy还支持属性注入和方法调用注入,下面有个例子。

ProductService类引用了SupplierData(下面代码没定义)类,也就是依赖它了。Unity不会自动设置去创建一个实例的,你必须明确地配置容器。一种是使用Dependency特性,如下:

public class ProductService
{
   private SupplierData supplier;
   [Dependency]
   public SupplierData SupplierDetails
   {
    get { return supplier; }
    set { supplier = value; }
   }
}

现在你通过Unity来创建ProductService实例的时候,就会自动创建一个SupplierData 实例,并给这个属性赋值,换句话说,SupplierDetails对象不是空的了,本来我们使用SupplierDetails,肯定是空的,使用起来就会报错,但是如果加上Dependency特性,就不会报错了。

2.4.3 填充和注入数组, 泛型数组

你可以定义数组,泛型数组,代码运行的时候,Unity就会自动给数组赋值(注入数据),让它不是空的了。你可以指定数组的成员,或者使用Unity将配置中所定义的匹配类型自动填充到数组中。接着你就可以直接使用这个数组了。然后你可以直接使用数组作为类型填充,或者设置成构造函数的值、方法的参数成员和属性。数组可以被定义在配置文件中或通过代码在运行时定义。

更多的信息参考:

    • 配置注入参数和属性值 (Configuring Injected Parameter and Property Values)
    • 注册注入参数和属性值 (Registering Injected Parameter and Property Values )
    • 注册泛型参数和类型 (Registering Generic Parameters and Types )

2.5 拦截(Interception)对象的调用

在面向对象的系统中,对象的职责是单一的 那是最好的。随着系统的开发,很多需求就会增加。比如系统的监视相关的:日志,时间计数器,参数验证和异常处理。横向切割(AOP)可以解决有些情况下代码重复的问题。代码重复带来的问题,比如说,如果一处发生改变,那么你就要改很多地方,所以比较麻烦。

拦截技术(Interception)使你能够在调用目标对象之前或之后增加代码,举个例子,调用方法之前,判断用户是否有权限,有权限就调用呗。

当你手动执行此编码过程,接下来你会知道什么被称之为装饰模式。编写装饰模式需求需要在设计开始知道类型的问题,同時要求每一个不同的装饰类型配合你所写的类型。

原文地址:https://www.cnblogs.com/AaronYang/p/3534835.html