SCSF - Part 4 An Aside on Inversion of Control, Dependency Inversion and Dependency Injection

Introduction

In part 3 of this series of articles I discussed dependency injection in general terms. To understand what the CAB is doing for you it’s important to have an understanding of dependency injection, and I will be talking more about it in part 5.

part3 我讨论了依赖注入, 为了更好的理解cab为你带来了哪些东西,理解依赖注入是非常必要的,我会在part5里面继续讨论。

 

This short article is something of an aside however, and is not critical for an understanding of the CAB. Here I will discuss two concepts that sound similar: inversion of control (‘IoC’) and dependency inversion. I will also discuss how both relate to dependency injection.

这篇短文对于理解cab来说不是最重要,我将在这里讨论两个听起来比较熟悉的概念,反转控制和依赖注入,我也会讨论他们和依赖注入的联系。

 

‘Inversion of Control’

‘Inversion of Control’ is currently something that everyone agrees is a good thing, even though no-one seems to be able to agree exactly what it is. For example, on Wikipedia there’s no definition of Inversion of Control, only an admission that we can’t define it.

反转控制室近期被大家认可的一个很好的东西,即使看起来没有人能准确的认同它是什么。 举例来讲在以上链接中, 这里没能完全理解,⊙﹏⊙b汗

 

Inversion of control is closely related to dependency injection, as I will describe below, and is often used synonymously with it. However, it has a wider meaning, and is arguably not strictly accurate when applied to dependency injection as an abstract concept. Martin Fowler discusses inversion of control at length, but in hisarticle on dependency injection decides to avoid the term.

反转控制与依赖注入密切相连,我将如此描述它,并且将来这近似的使用,然而,它有更宽广的意义, 这里也没能完全理解 ⊙﹏⊙b汗

 

 

Inversion of Control in Relation to Frameworks

The conventional definition of inversion of control relates to frameworks and code re-use. Normally to re-use someone else’s code you would call into a library. You do this all the time in the .NET framework. For example, if you call Math.Tan() you are using someone else’s code, but you make the call and you have control.

对于反转控制有一个约定俗成的定义是关系到架构和代码的重用,通常对于重用他人的代码我们会从类库中调用,在。netframework里我们一直这么用, 举例来说, 当我们调用 math。tan() 你调用了其他人的代码,但是你调用了并且控制了它。

However, there are times using .NET when the framework calls you back. An example is when you write a custom array sort algorithm using the IComparable or IComparer interfaces. Another is when you implement a custom enumerator by implementing IEnumerable on a collection class. In these cases the usual direction of control is inverted: something else is calling your code, rather than you calling something else.

然而, 有时候 。netframework会调用你写的函数, 一个例子就是当你写了一个你自己的数组排序的算法,你使用了Icomparable 和Icomparer 接口, 还有就是你可以通过IEnumerable接口客户化你自己的计数器。 这个时候调用发生了反转,别的东西正在调用你的代码,而不是你在调用他人的。

 

Example

If we implement IComparable on a class we have to write a method called CompareTo(). This defines when one object of the class’ type is bigger than another. Then when we call Array.Sort on an array of objects of this class the framework itself calls our routine to sort the objects according to our definition.

如果我们实现了Icomparable 这个接口,我们必须实现这个函数compareto(),这定义了什么时候这个类的一个对象比另一个大。 这样,当我们调用 array。sort()给这个对象数组排序的时候,framwork自己会调用我们定义的函数。

 

I’ve written a simple example to illustrate this.

Here the .NET framework is calling my code, and as a result I have to write it with a specific method signature – int CompareTo(object obj). I don’t have direct control over when this call is made. We can think of this as an ‘inversion’ of ‘control’ from the Math.Tan example.

For obvious reasons, the inversion of control concepts described above are often called the ‘Hollywood Principle’, or ‘don’t call us we’ll call you’.

在这个例子中 netframwork调用了我的代码, 我写的这个函数必须符合这个签名 int compareto(object obj), 我没有直接的控制什么时候这个调用被实现, 我们可以把这个看做是 反转控制。   因为显而易见的理由,以上反转控制的概念被叫做 “好莱坞原则”,或者 “不要call我们,我们会call你”。

 

Summary

Inversion of control is discussed in relation to frameworks in ‘Design Patterns: Elements of Reusable Object-Oriented Software’ by Gamma, Helm, Johnson and Vlissides (also known as the ‘Gang of Four’ book). They summarize quite nicely:

“Frameworks emphasize ‘design reuse’… Reuse on this level leads to an inversion of control between the application and the software on which it’s based. When you use a toolkit (or a conventional subroutine library for that matter), you write the main body of the application and call the code you want to reuse. When you use a framework, you reuse the main body and write the code it calls. You’ll have to write operations with particular names and calling conventions, but that reduces the design decisions you have to make.”

关于反转控制的讨论,可以参考某某某 , 他们总结得非常好;

“framework加强了“设计重用” 在这个级别的重用导致了 应用程序和软件之间的反转控制,当你使用一个工具包,你在你的程序了写了主干代码,并且调用了你想要重用的代码,当你使用framework时 你将重用主干代码,并且写下主干代码将要调用的代码。你将不得不写一些拥有特殊名字的操作。 但这减少你需要做出的在设计方面的决定。

 

Inversion of Control and Dependency Injection

So how does inversion of control relate to dependency injection? At first glance the concepts above and my examples in the previous article have little in common. Yet the two terms are often used synonymously. Indeed I have some course notes from a major computer trainer that actually says ‘IoC and dependency injection are terms that mean the same thing’.

The answer is that dependency injection is usually done via a framework of some kind. I will discuss this more in part 5, but typically you define your classes and then tell the framework to ‘inject’ them into other classes in some way. The framework is then calling back your code to do the injection, and we have inversion of control as described above.

反转控制和依赖注入有怎样联系的呢?  我之前的文章对他两的解释有些相同点。甚至他们的使用也很相近, 我确实上过一些课程说 这两样东西有着共同的意思。

答案是依赖注入是用framework完成的,我将在part5继续讨论, 但是 典型的你定义了一个class 并且告诉framework 去注入他们到其他class里,然后framework会调用你的注入,如此,我们拥有了之前描述的反转控制。

 

 

Inversion of Control = Dependency Injection?

As I’ve discussed, dependency injection is just one very specific example of how inversion of control can be used. As a result it is probably wrong to treat IoC and dependency injection as terms that mean the same thing. IoC is a wider concept.

However, in spite of it not strictly being accurate, when people talk about ‘IoC Containers’ and ‘IoC Frameworks’ what they usually mean are containers or frameworks that do dependency injection.

正如我讨论过的, 依赖注入是一种非常特殊的例子告诉我们反转控制是如何被使用的,事实上,把这两者看做一样是错误的,反转控制是个更广泛的概念。

然而,尽管那不是非常的准确-----当人们谈论到反转控制的容器和反转控制的framework 他们常说是containers和framework在做依赖注入

 

 

Inversion of Control and the CAB

The Composite Application Block really is an inversion of control framework in all senses by the way. It allows us to do dependency injection, as I’ll describe below (eventually). It also is often calling us rather than us calling it. An example of this is the call to the ‘Load() method in a ModuleInit class at start up that we saw in Part 1 of this series of articles. We have to just know that method will be called when the module starts, and code to the method signature.

cab 确实是一个反转控制的架构, 它允许我们做依赖注入,它经常是调用我们的函数而不是我们调用它, 一个例子就是, moduleint 类里的load() 函数的调用, 我们只是知道 当模块启动的时候,这个函数会被调用。

 

Dependency Inversion

A related concept that causes further confusion is dependency inversion. Once again dependency inversion is a wider concept that is used in dependency injection. The aim of dependency inversion is to prevent high-level classes directly depending on lower-level classes and thus introducing tight-coupling between them. Instead we get both sets of classes to depend on interfaces.

另一个会导致更多困惑的相关概念是 注入反转。。 再次腔调, 注入反转是在依赖注入里使用的一个宽广的概念,这个注入反转是为了防止 high-level 的类直接依赖于 low-level的类,这样会导致他们之间的紧耦合, 我们要让他们都去依赖接口。

 

Dependency Inversion in the Example from Part 3

Consider my example of a main class and dependent classes from part 3. If you were writing this example in a ‘traditional’ way you might have the client code (class Program) create the MainClass which in turn would decide which dependent class it needed and instantiate it. The dependencies between classes would look something like this:

Direct Dependency Class Diagram

As we know, direct dependencies between classes are in general a bad thing as they make it harder to change the code in the dependent classes. So in our dependency injection pattern we introduce a specific interface that all our classes depend on in some sense:

Dependency Injection Class Diagram

Now, as discussed previously, the code is less brittle as we can change the dependent classes without worrying too much about breaking MainClass, as long as we don’t change the interface.

这里再次将了part3的例子,将了使用接口的好处,不一字一句的翻译了。

 

 

Dependency Inversion and Inversion of Control

We have inverted the dependencies for the dependent classes here. Previously they were being referred to directly by MainClass. Now nothing refers to them directly, instead they refer to the interface. The arrows from the dependent classes now point up instead of down.

Note that this is NOT inversion of control. We are inverting dependencies between classes. This is not an example of a framework calling the code rather than the code calling the framework. In both cases here ultimately MainClass calls code that runs in a dependent class.

我们在这里已经做了倒置, 之前他们直接和mainclass耦合, 现在不在直接耦合,而是和接口耦合,依赖关系发生了逆转 注意 这不是反转控制,我们这是在反转类之间的依赖关系, 这不是一个什么framwork调用我们代码还是我们代码调用framework的问题,最终主class调用的code在一个独立的class里运行着。

 

Conclusion

After the fairly lengthy discussion of dependency injection and inversion of control in the last two parts of this article I will return to discussing the CAB in part 5.

在花了两篇文章讨论了反转控制和依赖注入之后,我会在part5里继续介绍cab

 

References

Many code design books make a clear distinction between the dependency inversion I have described in this section and full ‘inversion of control’ (the Hollywood principle). For an example see the excellent ‘Head First Design Patterns’ book:
http://www.amazon.com/Head-First-Design-Patterns/dp/0596007124/ref=pd_bbs_sr_3/104-5057575-3250306?ie=UTF8&s=books&qid=1185706020&sr=1-3

As mentioned, Wikipedia is as confused as everyone else about IoC:
http://en.wikipedia.org/wiki/Inversion_of_Control

Martin Fowler is of course excellent on the subject:
http://martinfowler.com/bliki/InversionOfControl.html
http://www.martinfowler.com/articles/injection.html

The Gang of Four book discusses Inversion of Control in a section on frameworks:
http://www.ternion.com/news/Papers/1995_-_Design_Patterns_by_Eric_Gamma.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值