Unity学习系列一简介

时间:2024-08-01 10:04:56

一、简介

Unity的目标是为了提升"依赖注入"的思想,去建立更加松耦合的系统.patterns & practices 小组在那个时候实现DI的方式和我们现在认为的DI有所不同,DI不是单一的可重复使用的容器,而是应该专门用于正在使用它的系统.

我们使用一个叫做ObjectBuilder的类库(一个用于创建DI容器的框架),所以,理论上我们可以为我们的每一个项目创建一个容器,这正是我们想要做的.理想很美好,但是它工作的并不是很好,ObjectBuilder是一个高度解耦、抽象的,使用它必须手动组装它,再加上缺乏文档,花了很多时间了解需要去哪里,以及如何将其整合到有用的东西中去,而这些时间花在了编写、调试和优化DI容器上,而不是在实际的项目需求上工作上。有趣的是当有人想要引用CAB(它使用了一个基于一个版本的DI容器ObjectBuilder)和企业图书馆(基于不同版本的ObjectBuilder)在同一个项目中。集成将会变得非常困难。光光在同一个项目中处理两个不同的版本ObjectBuilder,也是一个不小的挑战。还有一次性的容器导致了一次性的可扩展性和集成接口:在企业库中没有用的在CAB中也没有用。

当我们在Web客户端软件工厂项目的末尾又花了一个星期的时间修复了CWAB中的一堆bug:(这些bug和在CAB中的非常相似),所以为什么不用一个容器实现,代替重复的实现一个又一个的容器。

由此产生的挫折感使人们团结起来。EnterpriseLibrary 4.0团队将依赖注入应用程序块(最初称为Unity)放在产品待办事项上。,我们对于Unity这个项目的目标很简单,。首先,向我们的社区引入并推广依赖注入的概念,不受许多低级别实现细节的限制。第二,有一个具有易于使用API的核心容器,我们、Microsoft的其他团队或任何组织不愿意使用可用的开源项目的人(无论出于什么原因)都可以使用这些API。第三,有多种扩展机制,这样任何人都可以添加新功能,而不必打开核心代码。

在我看来,Unity在所有这些目标上都取得了成功。我对我们如何影响.NET开发人员社区感到特别自豪。Unity很快成为.NET生态系统中最常用的DI容器之一.更重要的是,DI不再是"专家技术",而是主流的一部分,甚至是微软自家的框架(ASP. NET MVC and WebAPI)均来自DI的支持.你得知道,一个概念(依赖注入)变成一个核心观点,Unity发挥了很大的作用.

二、使用Unity的条件

1、支持的架构:x86和x64.·

2、操作系统:Windows 8、Windows 7、Windows Server 2008 R2、Windows Server 2012。·

3、支持的.NET框架:Microsoft.NET Framework 4.5、.NET for Windows Store应用程序(以前称为WinRT)。·

4、支持的开发环境:MicrosoftVisualStudio 2012、专业版、终极版或速成版。

可以使用VisualStudio中的NuGet包管理器在项目中安装统一程序集。

三、介绍

1、动机(Motivations)

当您设计和开发软件系统时,有许多需求需要考虑到。一些是具体的系统问题,一些是通用的问题。您可以将一些需求分类为功能性需求,以及一些非功能性需求。对于每个不同的系统,需求将会有所不同。下面列出的需求是常见的需求,特别是对于lineof-business(LOB)具有相对较长的预期寿命的软件系统。当然它们并不一定对你所开发的每一个系统都很重要,但是你可以确定其中的一些将会出现在你所从事的许多项目的需求列表中。

2、可维护性(Maintainability)
当系统变得更越来越大,预期寿命也变得越来越长,维护这些系统变得越来越困难。随着开发这个系统的项目成员的调整,就没还是原班人马,但是他们可能忘记了系统上的一些细节.文档可能已经过时了,甚至丢失。同时,企业可能要求迅速采取行动,一些紧迫的新业务需要。 可维护性是软件系统的一个重要的特性,那决定了你如何高效并且轻松得去更新和维护他.如果你发现了必须修复的bug(换句话说,执行常规的维护保养),那这个时候必须去更新一个系统,如果操作环境变化,要求你必须对系统进行改进,或者你需要加入一个新的特性去满足业务需求(perfective maintenance[改善型维护]).可维护的系统提高了系统的灵活性而且减少了系统的开销.因此,您应该将可维护性作为您的设计目标之一,以及可靠性、安全性和可伸缩性等优点。
3、可测试性(Testability)
一个可测试系统可以使你有效地测试各个部分的系统。设计和编写有效的测试和设计和编写可测试的应用程序代码一样具有挑战性.特别是当系统特别大和复杂的时候.测试驱动开发(TDD),在编写任何实现新代码之前,需要编写单元测试。这种设计技术的特点和目的是提高你的应用程序质量。这种设计技术也有助于扩大你的单位测试的覆盖范围。减少回归测试的可能性.使重构变得尽可能的简单.然而,作为测试过程的一部分,您还应该包含其他类型的测试。例如验收测试、集成测试、性能测试和压力测试。由于在现实环境中进行测试,运行测试需要花费金钱和时间。例如,对于某些类型的测试,并且测试的载体在云上,所以您需要将应用程序部署到云环境并在云中运行测试。由于部署应用程序需要花费时间的原因,在云中运行所有的测试是不切实际的。甚至是本地模拟器,在这种情况下,您可以决定使用测试双打(简单的存根或可验证的模拟)。用测试实现替换云环境中的实际组件。为了使您能够在隔离期间运行您的单元测试套件。在标准的TDD开发周期期间.可测试性应该是您的系统的另一个设计目标。可维护性和敏捷性:可测试的系统通常更易于维护。亦然。
4、灵活性和可扩展性(Flexibility and Extensibility)
一个好的企业级应用活性和可扩展性也是必备的.考虑到需求经常变化,无论是在应用程序的开发过程中还是在生产中运行之后,您都应该尝试将应用程序设计成灵活的应用程序,使其能够以不同的方式和可扩展的方式工作,从而可以添加新的功能。例如,您可能需要将您的应用程序从部署到本地转换成部署到云端.
5、延迟绑定(Late Binding)
在某些应用场景之下,如果你需要替换部分系统不编译,那么延迟绑定(Late Binding)非常有用.例如,你的应用系统可能需要支持多种关系型数据库,对于每种数据库类型,你都需要一个单独的模块来支持.你可以使用申明式的配置告诉应用程序在运行时加载对应的模块.另一个延迟绑定(Late Binding)可能有用的场景是,使系统的用户能够通过插件提供他们自己的自定义。您可以通过使用配置设置或约定指示系统使用特定的自定义,其中系统扫描文件系统上的特定位置以供模块使用。
6、平行开发(Parallel Development)

当你在开发大规模(甚至是中小型)系统,让整个开发团队同时在相同的特性或组件上工作是不实际的.事实上,你将不同的特性和组件分配给要并行处理的小组。虽然这种方法使您能够缩短项目的总体工期。它确实带来了额外的复杂性.您需要管理多个组,并确保可以集成由不同组开发的应用程序的各个部分,以便正确地一起工作。

7、横切关注点(Crosscutting Concerns)
      企业级应用程序经常需要处理一些横切关注点,例如验证、异常处理、日志.您可能需要在应用程序的许多不同领域中使用这些特性,并且希望以一种标准、一致的方式来实现它们,以提高系统的可维护性。理想情况下,您需要一种机制,使您能够在设计时或者运行时高效透明地向对象添加行为.而不用对现有类进行修改.横切关注点请参考Aop学习笔记系列一
8、松耦合(Loose Coupling)
您可以通过确保您的设计在一个应用程序中松散地将组成应用程序的许多部分连接在一起,来满足前面章节中列出的许多需求。松耦合,相对于紧耦合意味着减少构成系统的组件之间的依赖关系.这使得在系统的一个区域中进行更改变得更容易和更安全,因为系统的每个部分在很大程度上都是独立的.
9、一个简单的例子
下面的示例说明了ManagementController类直接依赖TenantStore类的紧耦合。这些类可能在不同的VisualStudio项目中。在本指南中,ManagementController和TenantStore类以各种形式使用
    public class TenantStore
{ public Tenant GetTenant(string tenant)
{ }
public IEnumerable<string> GetTenantNames()
{ }
} public class ManagementController
{
private readonly TenantStore tenantStore;
public ManagementController()
{
tenantStore = new TenantStore();
}
public ActionResult Index()
{
var model = new TenantPageViewData<IEnumerable<string>>
(this.tenantStore.GetTenantNames())
{
Title = "Subscribers"
};
return this.View(model);
}
public ActionResult Detail(string tenant)
{
var contentModel = this.tenantStore.GetTenant(tenant);
var model = new TenantPageViewData<Tenant>(contentModel)
{
Title = string.Format("{0} details", contentModel.Name)
};
return this.View(model);
}
}

在本系列中,ManagementController和TenantStore类以各种形式使用,尽管ManagementController是一个Asp.Net Mvc控制器.您不需要了解MVC来跟进。但是,这些示例看起来像在现实世界系统中遇到的类,特别是第3章中的示例。

在这个例子中TenantStore类实现了一个仓储,该仓储处理对基础数据存储(例如关系数据库)的访问,ManagementController是一个MVC控制器,它从仓储请求数据,注意,ManagementController类必须先实例化TenantStore对象,或者在调用GetTenant和GetTenantNames方法之前,从其他地方获取TenantStore店对象的引用。ManagementController类依赖于特定的具体TenantStore类。

如果您在本章开始时参考了企业应用程序常见的理想需求列表,您可以评估前面代码示例中概述的方法如何帮助您满足它们。虽然这个简单的示例只显示TenantStore类的单个客户端类,实际上,应用程序中可能有许多使用TenantStore类的客户端类。如果假设每个客户端类负责在运行时实例化或定位TenantStore对象,