[Study Note] Dependency Injection and Inversion of Control

之前,一直没有搞明白这两个概念,这次原本打算学习一下 StructureMap,结果被迫补课,总算是对它们多少有了一点印象。

出来混,总是要还的。

[Before you use an IoC tool, some concepts to know first]

well designed Object Oriented systems are composed of many objects that work with each other to accomplish to goals of the system. We want our systems to be decomposed into cohesive class that perform a well defined responsibility within the system, rather than monolithic "God" classes that to to too much. A Cohesive class will have to be dependent upon other classes to perform services out side of its own tighly defined responsibility. In IoC speak, we call the collaborating objects dependecies.

ObjectFactory is a StructureMap class that serves as a well known place to go  and find any service that you need.

Auto Wiring simply means that StructureMap can figure out dependency chains for you without a lot of explicit configuration.

 

[Inversion of Control]

"contructor injection"

  • Setting up the tests.
  • The tests are isolated.
  • Debugging.
  • Test execution time.
  • Code reuse. 

这篇文章看完之后,我对于 Inversion of Control 并没有特别清晰的概念,从示例代码来看 Miller 仅仅只是把涉及数据库访问的那部分代码剥离了出去;再加上之前的一些解释,可以理解为让那个 Translator 转换控制类”依赖于 sender(CompanyInfo) 和 receiver(CompanyInfo)两个对象,而不是之前的传递的 senderId 和 receiveId。

难道如此简单就是传说中的 IoC ?

Hollywood Principle – ”Don’t call us, we’ll call you”

A tool should arrange for Tajo to notify it when the user wishes to communicate some event to the tool, rather than adopt an ‘ask the user for a command and execute it’ model.

Inversion of Control is a key part of what makes a framework different to a library.

A library is essentially a set of functions that you can call, these days usually organized into classes. Each call does some work and returns control to the client.

A framework embodies some abstract design, with more behavior built in. In order to use it you need to insert your behavior into various places in the framework either by subclassing or by plugging in your own classes. The framework’s code then calls your code at these points.

 

 

[Dependency Injection]

In a nutshell, dependency injection just means that a given class or system is no longer responsible for instantiating their own dependencies.

  1. Dependency Injection is an important pattern for creating classes that are easier to unit test in isolation
  2. Promotes loose coupling between classes and subsystems
  3. Add potential flexibility to a codebase for future changes
  4. Can enable better code reuse
  5. The implementation is simple and does not require a fancy DI tool

different flavors of Dependency Injection

  1. Constructor Injection --  Attach the dependencies through a constructor function at object creation
  2. Setter Injection --  Attach the dependencies through setter properties
  3. Interface Injection – odd duck. specific DI tools in the Java world
  4. Service Locator – Use a well known class that knows how to retrieve and create dependencies. Not technically DI, but this is what most DI/IoC container tools really do.

Constructor Injection

push the dependencies in through the constructor function.

benefits -- explicitly declares the dependencies of a class, expresses a contract, create a valid object in as few steps as possible for ease of use.

Setter Injection

creating a setter property to replace a dependency on a previously instantiated object.

Setter Injection does work and is often necessary when you’re dealing with existing code.

Michael Feathers recommends using Setter Injection as a dependency breaking technique for legacy code when a dependency is too difficult to expose through a constructor.

Service Locator

creates a level of indirection between a class and its dependencies.

StructureMap’s ObjectFactory class

 

Mock Driven Design

 

Dependency Injection leaves an easier migration path to eliminate the legacy code later with all new code.

Dependency Injection increasing the potential for reuse later.

 

2010-03-30 06:45

 

[Service Locator]

component mean a glob of software that’s intended to be used,  without change, by application that is out of the control of the writers of the component. 

service used by foreign applications.

a component to be used locally ( think jar file, assembly, dll, or a source import).

a service will be used remotely through some remote interface, either synchronous or asynchronous ( eg web service, messaging system, RPC, or socket.)

service locator is to have an object that know how to get hold of all of the services that an application might need.

A way to think of  this is that service locator is a registry not a singleton.

  • Using a Segregated Interface for the Locator
  • Dynamic Service Locator
  • Using both a locator and injection with Avalon

 

2010-03-30 22:15

Service Locator vs. Dependency Injection

The important difference between the two patterns is about how that implementation is provided to the application class. With service locator the application class asks for it explicitly by a message to the locator. With injection there is no explicit request, the service appears in the application class – hence the inversion of control.

with a Service Locator every user of a service has a dependency to the locator. The locator can hide dependencies to other implementations, but you do need to see the locator.

Using dependency injection can help make it easier to see what the component dependencies are. With dependence injector you can just look at the injection mechanism, such as the constructor, and see the dependencies. With the service locator you have to search the source code for calls to the locator. 

Constructor Injection vs. Setter Injection

Constructors with parameters give you a clear statement of what it means to create a valid object in an obvious place.

Constructor Injection allows you to clearly hide any fields that are immutable by simply not providing a setter.

start with constructor injection, but be ready to switch to setter injection as soon as the problem I’ve outlined above start to become a problem.

  • a lot of constructor parameters
  • multiple ways to construct a valid object
  • have simple parameters such as strings
  • have multiple constructors and inheritance

Code vs. configuration files

simple application that’s not got a lot of deployment variation – a bit of code can be clearer than a separate XML file.

the assembly is quite complex, involving conditional steps. – provider several builder classes and use a simple configuration file to select between them.

ADVICE: provide a way to do all configuration easily with a programmatic interface, and then treat a separate configuration file as an optional feature.

Separating Configuration from Use

within an object oriented program when conditional logic decides which class to instantiate, and then future evaluations of that conditional are done through polymorphism rather than through duplicated conditional code.

 

[Dependency Inversion Principle]

Dependency Inversion Priciple, DIP

Depend upon Abstractions. Do not depend upon concretions.

Rules of Thumb to Use DIP

  1. Anytime your code calls out of the CLR, and maybe just the current AppDomain itself.
  2. Singleton’s.
  3. Interface points between major subsystems.
  4. Extension points.

posted on 2010-03-30 23:06  zhaorui  阅读(213)  评论(0编辑  收藏  举报

导航