Introduction

Articles covering the latest in the developer world, tutorials on my new projects, elegant solutions to common programming problems and visionary thoughts on programming.

May 19th, 2006

Dependency Injection

Applications consist of multiple classes which collaborate with each other. For example an instance of class A needs an instance of class B and C to do its job; in other words, class A depends on class B and C; class B and C are thus dependencies of class A.

There are three options to satisfy dependencies:

  1. hard-code dependencies,
  2. look up dependencies,
  3. use the Dependency Injection pattern.

1. Hard-coding dependencies is the easiest strategy: class A simply instantiates its dependencies.

  1. class A {
  2.    
  3.     private var b:B;
  4.     private var c:C;
  5.    
  6.     public function A() {
  7.         b = new B(3, true);
  8.         c = new C();
  9.     }
  10.    
  11.     public function doSomething() {
  12.         var r:String = b.doSomething();
  13.         c.doSomething(r);
  14.     }
  15.    
  16. }

Problems of hard-coding dependencies:

  • Configuration is distributed across the whole application (configuration is in this case wiring up the instances and configuring dependent instances).
  • Class A must be modified to exchange a dependency (tight coupling): the instance of B may be replaced by an instance of SubB which fulfils the same contract as its super-class B. If B were an interface than any implementations could be used to satisfy the dependency.
  • What if a fourth class D has a dependency to the same instance of B as class A?

2. Looking up dependencies requires a context: class A gets the context and looks up its dependencies.

  1. class A {
  2.    
  3.     private var b:B;
  4.     private var c:C;
  5.    
  6.     public function A() {
  7.         var context:Context = Context.getInstance();
  8.         b = context.getB();
  9.         c = context.getC();
  10.     }
  11.    
  12.     …
  13.    
  14. }

Advantages of looking up dependencies:

  • Partially centralized configuration of the context: dependency b is already fully configured; but every instance looks up its dependencies on its own.
  • One instance can be used to satisfy multiple dependencies: an instance of class D can simply use context.getB() to get the same instance.

Problems of looking up dependencies:

  • Class A depends on a context: makes unit testing more difficult and the look ups are disturbing.
  • Code is bloated with dependency look-ups.

3. Using the Dependency Injection pattern is simple and places no requirements: class A provides ways to inject dependencies.

Advantages of dependency injection:

  • Configuration is centralized in one place: both configuration of instances and wiring up instances.
  • Dependencies can be exchanged easily (loose coupling).
  • Wiring up instances is made easy.

Problem of dependency injection: The wiring code may become rather complex if there are a lot of instances with a lot of dependencies to satisfy.

One way to go is to use Constructor Injection. In this approach class A declares a constructor with paramters for both dependencies; the dependencies are given on instantiation.

  1. class A {
  2.    
  3.     private var b:B;
  4.     private var c:C;
  5.    
  6.     public function A(b:B, c:C) {
  7.         this.b = b;
  8.         this.c = c;
  9.     }
  10.    
  11.     …
  12.    
  13. }

Advantages of constructor injection:

  • Dependencies cannot be changed after instantiation.
  • Initialization which requires all dependencies can be done directly in the constructor.
  • Instance is not in illegal state after instantiation.

Problems of constructor injection:

  • Parameter list of constructor may become very long (there may be a lot of dependencies, plus other information to pass to the constructor).
  • Parameters are distinguished by index and not by name, which may make the code harder to understand.

Another way to go is Setter Injection. In this approach class A provides setters for both dependencies; the dependencies are satisfied after instantiation.

  1. class A {
  2.    
  3.     private var b:B;
  4.     private var c:C;
  5.    
  6.     public function A() {
  7.     }
  8.    
  9.     public function setB(b:B):Void {
  10.         this.b = b;
  11.     }
  12.    
  13.     public function setC(c:C):Void {
  14.         this.c = c;
  15.     }
  16.    
  17.     …
  18.    
  19. }

Advantages of setter injection:

  • Constructor can be used to pass other information than dependencies.
  • Code is easier to understand because names rather than indices are used to distinguish dependencies.

Problems of setter injection:

  • Dependencies may not have been satisfied when needed.
  • Dependencies may be changed after ‘official’ initialization.
  • Initialization may have to be done after all dependencies are satisfied: init-method is needed.

While dependency injection is a pattern with many advantages, there are also some problems when used extensively, which can only be solved by an Inversion of Control Container. Such a container provides means of managing instances: lifecycle management (instantiating classes, setting dependencies, invoking init-methods, destroying classes), looking up managed instances, configuring managed instances, resolving dependencies.

In my following articles I’m going to present the As2lib Inversion of Control Container and show you how it solves the problems mentioned above and which other functionalities it provides (for example using its generic XML dialect to create UIs with ActionStep, AsWing, EnFlash or any other component library).

Further Reading: Inversion of Control Containers and the Dependency Injection pattern

March 5th, 2006

As2ant 1.5: Specify Swfmill XML within Task

You can now specify the swfmill xml directly in the task. The advantages are that you have only one file to maintain (build.xml) and that you can use ant properties within the swfmill xml.

  1. <swf src="${src.dir}/com/simonwacker/ant/Sample.as" dest="${build.dir}/sample.swf">
  2.   <xml>
  3.     <![CDATA[
  4.       <movie width="300" height="100" framerate="31">
  5.         <background color=’#FF8A00′/>
  6.         <frame>
  7.           <library>
  8.             <clip id="simonwacker" import="${res}/simonwacker.jpg"/>
  9.             <font id="pixel" import="${res}/pixel.ttf"/>
  10.           </library>
  11.         </frame>
  12.       </movie>
  13.     ]]>
  14.   </xml>
  15. </swf>

Further enhancements are:

[+] org.as2lib.ant.Mtasc
Added special XML support for As2lib Bean Factory and Context.

[+] org.as2lib.ant.Swfmill / org.as2lib.ant.Swf
Added support for specifying the swfmill xml directly in the tasks.

[+] org.as2lib.ant.Swf
Added support for overriding font family names.

[+] org.as2lib.ant.Swfmill / org.as2lib.ant.Swf
Added support for extra verbose debugging output.

Download As2ant 1.5 from sourceforge.net
Download As2ant 1.5 from simonwacker.com

I hope you enjoy the new features!

February 27th, 2006

As2ant 1.0 with As2api Task

As2ant 1.0 has just been released! Best new features are the new As2api task and the custom-arguments support for the Mtasc task.

Full list of changes:

[+] org.as2lib.ant.As2api
Added support for HTML API documentation generation via As2api.

[!] org.as2lib.ant.Mtasc
Fixed bug with package-argument: Use relative paths!

[+] org.as2lib.ant.Mtasc
Added support for custom arguments: <argument name=”-myargument” value=”myvalue”/>

[~] org.as2lib.ant.Mtasc
Ignore classes in source xml files that cannot be found.

[+] org.as2lib.ant.Mtasc
Added support for source xml files with ‘type’ as attribute.

[+] org.as2lib.ant.Mtasc
Improved commandline output by adding locations to all exceptions.

[~] org.as2lib.ant.Mtasc
Compile all source files in split-mode, even when one raises a compile error.

Download As2ant 1.0 from sourceforge.net
Downlaod As2ant 1.0 from simonwacker.com

If you find any bugs please report them!

October 13th, 2005

As2lib 0.9.3, New Version

A new version of the as2lib is finally available for download.

Major changes are:

  • A completely rewritten File framework that offers various file format representations, like properties files, and support for loading and parsing these files - org.as2lib.io.file
  • Support for configuring the Logging framework via XML - org.as2lib.env.log.parser
  • Improved Process and Unit Testing frameworks - org.as2lib.app.exec, org.as2lib.test.unit
  • Many bug fixes in the AOP framework - org.as2lib.aop
  • New Regular Expression (RegExp) framework (note that there is still much documentation missing) - org.as2lib.regexp

As you can see, it is definitely worth updating to this new version.

Download As2lib 0.9.3.

View API Documentation

If you find any bugs, report it, if you want a new feature, tell us about it, if you need support, ask us: Response.

The next releases will contain a Bean Factory and Application Context framework and of course - a documented Regular Expression (RegEx) framework. ;)
So, stay tuned!

October 13th, 2005

As2ant 1.0 beta, Released!

Changes include:

* Better readability of generated commandline output.
* Support for local variable inference: -infer
* Support for package-attribute: -pack
* New way of specifying sources, via XML

The new way of specifying sources via XML is especially important. Because this allows you to write a xml log configuration for the As2lib logging framework and specify this xml log configuration as source xml in your mtasc or swf tasks.

Check it out yourself!

Download As2ant 1.0 beta.

The next release will contain

* a task for As2api,
* fixes for all the bugs you encounter and
* implementations of new features you need.

I hope you enjoy working with the tasks!