Welcome

首页 / 软件开发 / .NET编程技术 / 微软名为Unity的依赖注入Application Block

微软名为Unity的依赖注入Application Block2010-07-09 infoq.com Robert Bazinet 译者 张善友微软模式与实践小组发布了叫做Unity或者Unity Application Block的依赖注入容器。开发人员现在能够利用可扩展的轻量级容器创建松耦合应用。

InfoQ有机会采访了Unity项目的开发领头人Chris Tavares。

Rob Bazinet (RB): Chris介绍一下你自己和你是如何参与Unity的?

Chris Tavares (CT):我的名字叫Chris Tavares。我是微软模式与实践小组的一名高级软件开发人员。我目前正在领导Enterprise Library 4和Unity Application Block的开发。我也写了大部分的Unity的代码,所以Unity的美丽都源于我的“错误”。我已经在模式与实践小组工作超过2年时间。在来微软工作之前,我从90年代开始从事工业软件外包,盒装软件开发,甚至一些嵌入式软件开发。

RB:Unity Application Block是什么?

CT:Unity是一个依赖注入(Dependency Injection,DI)容器。DI的标准描述文章来自Martin Flower[0]【译者注:中文译文参见[4]】。作为一个快速的摘要,依赖注入容器就是一个用于构建高度松耦合的软件的工具。依赖注入容器处理相互关联对象的所有细节,因此你可以构建一个独立的组件。这对可测试性和灵活性方面有很大的影响。

例如在一个银行系统的,你可以有一个对象,管理帐户转帐。要实现这个目标,需要获得个人账户的对象,再加上安全规则及审计方面的要求。通常的实现看起来是这样的:

AccountTransfer
{
TransferMoney( sourceAccountNumber, destAccountNumber, amount)
{
Account sourceAccount = AccountDatabase.GetAccount(sourceAccountNumber);
Account destAccount = AccountDatabase.GetAccount(destAccountNumber);
sourceAccount.Withdraw(amount);
destAccount.Deposit(amount);
Logger.Write(, amount, sourceAccountNumber, destAccountNumber);
}
}

可以想象,这是相当可怕的代码(例如没有事务管理),虽然其可以正常工作。;-)

这是很简单的,但也是高度耦合的。全局的AccountDatabase 类调用意味着你甚至不能单独编译,更别提进行测试了。如果帐号是来自两个不同的银行会发生什么呢?同样的,全局的日志记录器意味着你必须先获得一个某个明确全局记录器类所创建日志记录器后,才能使用这个类。这一结果在当你尝试编写单元测试的时候是很痛苦的,而且从长远来看也极大地限制了灵活性。

职责分离原则要求一个类不要有多个职责。在这里,这个类违反了这一原则,不仅关心如何转移资金的细节,而且还要知道如何从数据库中获取帐号和如何写日志信息。为了恢复灵活性,这些职责需要分离到不同的对象,然后在通过传递回这个对象来使用它们,看起来像这样:

AccountTransfer
{
IAccountRepository accounts;
ILogger logger;
AccountTransfer(IAccountRepository accounts, ILogger logger)
{
.accounts = accounts;
.logger = logger;
}
TransferMoney( sourceAccountNumber, destAccountNumber, amount)
{
Account sourceAccount = accounts.GetAccount(sourceAccountNumber);
Account destAccount = accounts.GetAccount(destAccountNumber);
sourceAccount.Withdraw(amount);
destAccount.Deposit(amount);
logger.Write(, amount, sourceAccountNumber, destAccountNumber);
}
}