Thoughts on Modern Web Development …

When working with the Adobe AIR SQL API it is important to consider the various best practices advocated by Adobe regarding performance, security and design. As there is nothing in particular in the SQL API itself to guide developers in following these best practices, developers are left to implement their own solutions, which often may vary across different applications.

For instance, consider the SQLStatement class. In order to optimize performance of the execution of a statement, the statement must first be prepared (i.e. compiled), which optimizes the statement by the runtime prior to execution. Once a statement is prepared, if the text property does not change, subsequent executions of the statement will execute faster. In order to facilitate this particular optimization developers must first be aware of this best practice, then determine the appropriate way to implement a solution in order to take advantage of the advocated practice. A simple way to facilitate this is to define separate SQLStatement instances for each unique statement which is to be executed more than once, as is suggested by Adobe, and assume the text property is not to be assigned a new value. You could take this a step further as well and define a sub class of SQLStatement which enforces the text property is only assigned a value once, thus ensuring the optimization has been set. The AIR SQL Framework provides such facilities.

The AIR SQL Framework is a simple, reusable framework which facilitates advocated best practices when working with the SQL API in AIR.

At the foundation of the AIR SQL Framework sits the following packages:

com.ericfeminella.sql The sql package contains a PreparedStatement class for enforcing a SQLStatement instance to only have a text value assigned during instantiation. In addition the sql package contains an ISQLStatementCache interface which can be used to indicate an implementing class is to serve as a repository of reusable PreparedStatement instances.

This distribution of the AIR SQL Framework should be considered an alpha release as there are some additional features which I am planning to implement, namely, the addition of support for named parameter substitutions in the SQLStatementHelper class.

I have provided an example project which demonstrates a simple AIR application built utilizing the AIR SQL Framework, along with the source, binary and documentation.

Fowler’s assessment of Inversion of Control containers concluded that the name itself – Inversion of Control – was too generic, thus as a result from his discussions with various IoC advocates they settled on the more specific term Dependency Injection, also known as DI for short. The terms Inversion of Control (IoC) and Dependency Injection (DI) are commonly used interchangeably to describe the same underlying design principle of separating configuration from implementation.

There are three basic forms of Dependency Injection, which are generally referred to as type 1 IoC (Interface Injection), type 2 IoC (Setter Injection) and type 3 IoC (Constructor Injection). Before diving into the specifics of how to implement the various forms of DI, I will first discuss what Dependency Injection is on a conceptual level as well as what each specific form means. The examples outlined here are in ActionScript 3, however it is important to keep in mind that like most Design Patterns Dependency Injection applies to any language which supports an Object Oriented Model.

At the most basic level Dependency Injection can be explained as a way of decoupling classes from their dependencies by injecting the dependencies into them rather than having the classes directly reference specific implementations. A class which directly references other classes is coupled to those classes – these are the dependencies. However a class which does not reference any other classes would probably not be very useful. At some point the dependencies need to be made. Dependency Injection is a solution to how those dependencies are made, and the manner by which they are provided.

For example, consider the following class which illustrates a typical example of a class’s dependency on another class:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

publicclassConfigurationManager

{

//defines the configuration to use

privatevar config:XMLConfiguration;

publicfunctionConfigurationManager()

{

config=newXMLConfiguration();

}

publicfunctiongetLogLevel():String

{

returnconfig.getConfig("logLevel");

}

}

From looking at the code above the dependencies are pretty obvious; the ConfigurationManager class is dependent on the XMLConfiguration class. Now this type of dependency is quite typical so at this point you may be asking what is wrong with doing this?

The first problem is that the config property is defined as a concrete implementation:

1

2

3

privatevar config:XMLConfiguration

This violates a fundamental OO principle:

Program to interfaces, not implementations.

More importantly and perhaps pertinent to the topic at hand is that it also isn’t very hard to imagine that at some point we may want to load a configuration from some other means, such as a properties file, a remote service and so on. In order to do so we would need to modify the class, and from this we can deduce that the class does not scale very well.

So we could begin improving our current implementation by simply refactoring the ConfigurationManager class to define the config property as an abstraction, say IConfiguration:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

publicinterfaceIConfiguration

{

functiongetConfig(name:String):*;

}

publicclassConfigurationManager

{

//define the configuration as an abstraction

privatevar config:IConfiguration;

publicfunctionConfigurationManager()

{

config=newXMLConfiguration();

}

publicfunctiongetLogLevel():Array

{

returnconfig.getConfig("logLevel");

}

}

As you can see this is certainly a step in the right direction, however the underlying problem still remains; we are still instantiating an instance of XMLConfiguration directly in the ConfigurationManager – and that is exactly what Dependency Injection is all about: providing a solution to the recurring problem of managing dependencies between classes, and how those dependencies are provided.

When implementing the Dependency Injection Pattern in an application you do so by creating a context (configuration) which defines all dependencies in an application as well as an Assembler which is responsible for assembling the mappings and associations between objects and their dependencies. This is done by utilizing any combination of the three forms of DI; Interface Injection, Setter Injection and Constructor Injection. Below is a brief description of each form:

Interface Injection
Interface Injection is the process by which all dependencies are injected into an object via an interface. For example, the ConfigurationManager example above could implement an interface which defines the operations needed to inject the appropriate Configuration implementation.

Setter Injection
Setter injection as you may have guessed is the process of injecting dependencies via public setters; both explicit or implicit. Using Setter Injection the ConfigurationManager could provide public setters from which an Assembler could inject the appropriate Configuration implementation.

Constructor Injection
Again as you may have guessed Constructor Injection is the process of injecting dependencies via arguments in the class constructor. Using Constructor Injection the concrete Configuration could just as easily be injected.

Both Constructor and Setter Injection are by far the preferred forms of Dependency Injection. Interface Injection has some major drawbacks as it somewhat leads to convoluted code since multiple additional interfaces need to be defined and implemented. The fact that “special” types need to be created and implemented in order to facilitate DI using Interface Injection greatly limits the potential for its use.

There are numerous frameworks for various platforms which provide out of the box Dependency Injection implementations for all three forms of DI. All of these frameworks handle the wiring necessary for easily implementing Dependency Injection in an application, the most notable being the Spring Framework for Java/J2EE. There are also quite a few DI solutions for Flex and ActionScript applications as well. Optionally you could choose to roll your own however I would first suggest investigating some of the frameworks which are currently available as they more than likely provide what you need. The Prana Framework by Christophe Herreman is a good choice as it is one of the most prevalent DI solution available at the moment for Flex.

Using the ConfgurationManager example from above I have provided a basic example application which demonstrates how to implement Dependency Injection utilizing the Prana framework. The example application uses constructor injection to provide a concrete Configuration to the ConfigurationManager, however I encourage you to experiment with the other mechanisms of injection as well. The example is intentionally kept very simple in that it is only intended to convey the basic concepts of DI and how to use it in Flex with Prana, from this you should have a good understanding of how to implement DI in a larger context.

Class annotations, also known as metadata in Flex, are extremely valuable as they allow developers to provide additional information about classes, properties and methods which may not be appropriate to convey through implementation details such as Marker interfaces or some other means. An annotation can be viewed as a comment of sorts that provides a facility which can be utilized to convey the intent of a class, property or method, however unlike comments annotations are compiled into byte code with the class, thus allowing inspection at runtime via object introspection / reflection. Annotations do not directly affect code semantics themselves, however they can be inspected at runtime which in turn may affect the semantics of the running application.

Annotations are also very useful for providing pre-compiler instructions for generating boilerplate code. Although custom annotations can not be used in this way directly in Flex, this usage can be found throughout the Flex Framework. A perfect example of how the Flex framework uses annotations to generate boiler plate code is the [Bindable] meta-data tag, which itself is an annotation as are all meta-data tags in Flex. When a class or property is defined as [Bindable] the pre-compiler in turn reads this attribute and generates the code which facilitates actual data binding; i.e. PropertyChangeEvent, IEventDispatcher etc.

In order to use custom annotations in Flex you first need to instruct the compiler to keep Actionscript 3 metadata. This is achieved by using the keep-as3-metadata compiler argument. An example of setting two custom metadata attributes named “Foo” and “Bar” in the Flex IDE under project > compiler options is as follows.

1

2

-keep-as3-metadata Foo,Bar

Additionally annotations can be specified in a flex configuration file as follows:

1

2

3

4

5

&lt;keep-as3-metadata&gt;

&lt;name&gt;Foo&lt;/name&gt;

&lt;name&gt;Bar&lt;/name&gt;

&lt;/keep-as3-metadata&gt;

When you create custom metadata in Actionscript you do so by first declaring the name of the annotation followed by arbitrary properties specified as name/value pairs. For example, you are most likely familiar with the [Event] metadata tag in Flex. The name of the annotation is “Event” and the valid properties for the annotation are “name” and “type”, as can be seen below:

1

2

[Event(name="eventName",type="package.eventType")]

Likewise you create your own custom metadata following the same format. The example which follows defines a custom metadata attribute utilized for annotating a class with version information. The name of the annotation is “Version”, which contains three properties; major, minor and revision.

To help simplify the process of accessing custom annotations in Flex I have developed a simple API: MetadataUtils which is an all static class that provides utility operations from which class annotations can be located and inspected, and Metadata which provides a strongly typed implementation of a metadata entry.

As you begin experimenting with your own custom annotations you will quickly find that there are numerous applications where they can be utilized, the most significant of which (IMHO) is to help facilitate IoC / DI solutions. It would be great if at some point Adobe would provide an APT implementation for mxmlc as part of a future release of Flex.