一、简介
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)具有相对较长的预期寿命的软件系统。当然它们并不一定对你所开发的每一个系统都很重要,但是你可以确定其中的一些将会出现在你所从事的许多项目的需求列表中。
当系统变得更越来越大,预期寿命也变得越来越长,维护这些系统变得越来越困难。随着开发这个系统的项目成员的调整,就没还是原班人马,但是他们可能忘记了系统上的一些细节.文档可能已经过时了,甚至丢失。同时,企业可能要求迅速采取行动,一些紧迫的新业务需要。 可维护性是软件系统的一个重要的特性,那决定了你如何高效并且轻松得去更新和维护他.如果你发现了必须修复的bug(换句话说,执行常规的维护保养),那这个时候必须去更新一个系统,如果操作环境变化,要求你必须对系统进行改进,或者你需要加入一个新的特性去满足业务需求(perfective maintenance[改善型维护]).可维护的系统提高了系统的灵活性而且减少了系统的开销.因此,您应该将可维护性作为您的设计目标之一,以及可靠性、安全性和可伸缩性等优点。
当你在开发大规模(甚至是中小型)系统,让整个开发团队同时在相同的特性或组件上工作是不实际的.事实上,你将不同的特性和组件分配给要并行处理的小组。虽然这种方法使您能够缩短项目的总体工期。它确实带来了额外的复杂性.您需要管理多个组,并确保可以集成由不同组开发的应用程序的各个部分,以便正确地一起工作。
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对象,