Dependency Injection without Reflection

Published by Manfred Karrer on Tuesday, 31 of January , 2012 at 21:46

Joa Ebert has written a Dependency Injection framework as part of his funk-as3 library.

Basically his API is orientated on Google Guice and does not use reflection, which is great, because reflection is pretty expensive regarding performance.

And Performance matters. We reduced the start-up time of our application from 8 seconds to 3 seconds just by removing Spring Actionscript and using a pure factory-based DI which does not use reflection and has no performance overhead. The code was also better to manage then the XML based solution of Spring Actionscript. Other frameworks which are more in the Guice-style would be nice to use but have the same negative impact on performance, so it was a No-Go for us. The drawback of our factory-based solution compared to Guice-style frameworks was, that it was not so easy and nice to use and more boilerplate code has to be written.

When stumbling over Joa Eberts DI framework I first wanted to use it directly as 3rd party library but I got some problems with the compiled swc. So I started to build my own small DI framework based on previous ideas in this direction and refined with some of his ideas and a similar API style. Unfortunately I cannot share the code but I can give the basic ideas.

So let’s get started:

First you need to setup the Locator. It’s a one-liner and is done like this:

[code lang="actionscript3"]myLocator = Locator.getLocator("myScope", myContext);
[/code]

The explanation for this will follow later.

Further you have a Context Class (the Module in Guice) where you define the bindings of what you want to get injected for a special Interface, Class or named annotation.

Additionally you define if the object should be only created once (asSingleton) or every time newly.

[code lang="actionscript3"]// Interface to Class
bind(ITestInterface).to(TestImpl).asSingleton();
 // String annotation to Class
bind("myList").to(ArrayCollection);
// Interface to instance
bind(IResourceManager).to(resourceManager).asSingleton();
[/code]

To support also some special classes which are outside of your control (3rd party) you can use a Provider to get an instance created in a custom fashion in the Providers getObject() method.

[code lang="actionscript3"]// String annotation to Provider
bind("myServcice").to(RemoteObjectServiceProvider).asSingleton();
[/code]

When you want to inject these objects somewhere in your Classes, just write inject(bindingKey) to obtain the instance defined in the Context.

But when not using reflection we are facing some problems.

Without reflection you don’t have information at run-time about the constructor arguments. This is a problem when creating the classes. One solution to prevent this problem is to use only constructors without arguments.

Instead of the classical way like here:

[code lang="actionscript3"]public function TestClass(testInstance:ITestInterface) {
    this.testInstance = testInstance;
}[/code]

We assign the mandatory members directly in the constructors body with the inject call.

[code lang="actionscript3"]public function TestClass() {
    testInstance = inject(ITestInterface);
} [/code]

Another solution would be to register the Class with it’s parameters annotations explicitly to the framework, so the information what needs to be injected when creating this Class is available.

Something like this (you can use a static function call as it is specific to the class, so it could be located directly above the Constructor):

[code lang="actionscript3"]registerClass(TestClass).withParams([ ITestInterface, "myList" ]);
public function TestClass(testInstance:ITestInterface,
                           myList:ArrayCollection) {
    this.testInstance = testInstance;
    this.myList = myList;
}[/code]

This would have the drawback that you need to maintain changes in the parameters in 2 places, and additional code needs to be written.

My preferred solution without constructor arguments has the drawback that the mandatory parameters are not visible in the signature of the constructor.
So both has some small penalties, but the good thing is it has zero overhead performance-wise and it is as easy to use like the classic Guice style injection.

Of course you can use the injection in properties or methods as well. But i prefer the constructor injection for all mandatory dependencies, so it’s more clear what a class needs initially.

So how does it work:

Technically it is not real injection but more like the Locator pattern.
You have a Dictionary where you define the mappings of keys (Interface, Class or named annotation as String) to instances, Classes or Providers.

What happened when calling the inject() method inside the Locator?
It looks up for the value stored for the given key.
That can be:

  • An instance, so return it.
  • A Class, so create an instance of this Class and return it.
  • A Provider. Create an instance of the Provider and call the getObject() method to get back an instance which is created in a customized way and return this instance.

The optional asSingleton() call is handling the behavior if the object is cached or not.

So why not use the Locator pattern?

When using the Locator  pattern you need the instance of the Locator. You can pass the Locator in the constructor to not rely on a static dependency inside your class.
That would be fine, but there is a more elegant way.

You can use a package level function (native Flash Functions like getTimer() or trace() are using this technique), so you can call directly the function without reference to the Locator. Inside the function it forwards the call to the package level property which got assigned the reference to the Locator from the setup. The “dependency” is only the package in which these 2 files are defined. If you follow a clear architectural structure this results in the positive side effect, that your Locator is used only in the correct scope and protects from cross-scope misuse.

Note that the file name must be the same like the Function or Property names (inject.as, myInjector.as) and only one Function/Property is allowed.
Here are code examples like these 2 files could look like:

[code lang="actionscript3"]package org.yourDomain.yourProject {
	public function inject(bindingKey:Object):Object {
		return myInjector.inject(bindingKey);
	}
}[/code]
[code lang="actionscript3"]package org.yourDomain.yourProject {
	import org.yourDomain.Injector;
	public var myInjector:Injector;
}[/code]

The myLocator property gets the concrete Locator instance assigned at the setup.

[code lang="actionscript3"]myLocator = Locator.getLocator("myScope", myContext);[/code]

Scopes:

When having a single project you probably don’t need to use different scopes, but this becomes important for larger projects. As different projects are normally using different root packages, the projects root package would be a perfect candidate for the scope key.
When you add the package level property and function file into these packages, you have in every project the access to the right scope of your Locator (need to import them where used).

The Locator implementation is pretty straight forward.

It does the management of the scopes as well as the mapping and handling (creation) of the instances when the inject() is called. I used the fluent interface style but you could implement the Binding also with a plain function and parameters.

Some final discussion:

So you may ask that fetching dependencies is not the same like injecting them, and classes should get the dependencies from outside instead of fetching them from inside.

Yes that is basically true.
But why it is better to get it injected?

Because normally to fetch something you need a reference to the container from where you get it. In classical ServiceLocator patterns it is mostly a Singleton.

[code lang="actionscript3"]ServiceLocator.getInstance().getObject("myObject");[/code]

Better would be to inject the ServiceLocator in the constructor, so the provider of your dependencies is free configurable and you don’t need to change your class if you want to use a different implementation of the provider.

It is not about getting or fetching, it it about to keep the class clean from static dependencies.

With the solution using package level functions it is less code needed to be written and has the benefit to implement a scope mechanism which can serve as protection.

Maybe it depends on the architecture and structure of the project if this approach makes sense. Another solution would be to pass the scope to the Constructor of the Class and lookup for the Locator inside the constructor with the scope key. Or simply pass the already resolved Locator instance typed as Interface to the Constructor.

So using it a bit different, the good old ServiceLocator mimics the fancy Guice-style Dependency Injection without really hurting, but saving a lot of performance.

Comments (9)

Category: Actionscript,Flash,Flex,Performance

Flex Life Cycle

Published by Manfred Karrer on Thursday, 20 of January , 2011 at 23:41

After working 10 years with Flash and 3 years with Flex I am still not convinced that the Flex Life Cycle is necessary.

I discussed this topic already with many developers but nobody could really give me a satisfying answer.
So I spread out my thoughts now to the public in the hope to get some valuable feedback.

Of course I am familiar with the concept of the Flex Life Cycle and the “elastic racetrack” behavior of the Flash Player.

The reason why I am not a friend of this concept is because it introduces an asynchronous code execution where a synchronous code execution would be much easier and faster.

In all my ActionScript based projects it was never necessary to use this pattern and defer code execution to another frame (or Render Event).
At bwin we have built a similar application as the current Flex-based Live Betting application previously in AS2, with a lot of complex components and auto layout containers, without running into any serious problems.
And to be honest the performance of the AS2 project felt somehow the same as the Flex version. But AS3 is about 10 times faster (of course that´s a bit too simple said and we did not measure the difference, but I am not the only one complaining about poor Flex Performance).

So isn´t it valid to question the concepts Flex is based on?

I am sure the architects at Adobe have had good reasons why they decided to introduce this pattern.
In the Docs and Blogosphere one can find several papers about it, but none of these explanations satisfied me, and some are not telling the full truth (that code execution is deferred to another frame).

So I try to discuss some assumptions for possible reasons:

  • Avoid Performance bottlenecks
  • Keep the Frame-rendering fluidly
  • Avoid Performance penalty from unintended repeated method (setter) calls
  • Pattern for separating different concerns
  • Problems with reading out the measurements of DisplayObjects before they are rendered on screen
  • Problems with complex execution flow from auto-layout containers code

So let me add my thought to these points:
Avoid Performance bottlenecks

That was my first assumption when I started with Flex, that this pattern is used to avoid performance bottlenecks. First I thought there is a hidden mechanism for detecting code execution which is running too long and delay this execution to the next frame. After checking out the SDK code I found out that it is simply delaying the 3 phases to 3 “half-frames” (Render Events and Enter Frame Events). So if you have really heavy code your player is still freezing up for a certain time and the Life Cycle does not give you any support for solving this problem.

That leads to the next argument:
Keep the Frame-rendering fluidly

Delaying the render code to the next frame helps the Flash Player running more smoothly and fluidly. That is basically true, but in my opinion 90% of the time the Life Cycle is wasting performance. For me it is a bad trade to get maybe at startup time some more fluidly running pre-loader animation but startup time takes much longer.

Why the Life Cycle is wasting Performance?
Because code which normally would be executed in one frame is now executed over 2 frames (or more).

There is another related issue with performance:
Avoid Performance penalty from unintended repeated method (setter) calls

Assume that in a large project it could be hard to control the execution flow so that it could happen that setting a text or layout property to a component is not only applied once but unintended multiple times.
For this scenario the Life Cycle helps because the call to the setter of the property is relatively cheap, so if the setter is called 10 times instead of once it will not hurt much. Then at commitProperties the property is only applied once to the component.
Again some weird scenarios with multiple invocations of commitProperties will not hurt much because the applying of the property to the component should be protected by a “changed” flag (see best practice with the Flex Life Cycle).
Also if you need for layout code some measurements the pattern helps to avoid unnecessary and repeated code executions.
BUT – is poorly written code really the reason why this pattern was introduced? It is true that it gives you some kind of fault tolerance, performance-wise. I guess this argument should not count in professional software development, and in fact it is dangerous because it could hide some deeper problems. If your setters are called more then once, why not look for the reason and clean it up?
I know in complex situations this could be sometimes hard, and under real life circumstances and time pressure you have to deal with something like this. But it should not count as a criteria for such a basic framework design decision.

I made also some measurements to check out the performance penalties for repeatedly called setters:

With 100 000 iterations applying a changing text to a TextField (in a AS3 project) I got these results:

1. Case:
Setting the text property to a variable in a loop and then applying the already stored text to the TextField again in a loop:

[code lang="actionscript3"]setText(): 119ms
applyStoredText(): 481ms
[/code]

In contrast to applying the property directly to the TextField:

[code lang="actionscript3"]
setAndApplyText(): 2879ms
[/code]

So you can see it is much slower in the 2. Case, so the Life Cycle really helps here, because it only applies the last stored property and not the changing values in between. But again – setting multiple times unnecessary property values is another problem.

The same test with setting the x position does not deliver such a big difference, in fact it is nearly the same time consumed (40+52 vs. 114)

[code lang="actionscript3"]setXPos(): 40ms
applyStoredXPos(): 52ms
setAndApplyXPos(): 114ms
[/code]

Let´s continue with the next point:
Pattern for separating different concerns

To have a kind of pattern which separates different concerns is basically a cool thing. So you have your code block for setting properties, another method where the properties are applied to the component, a method where the measurement is defined and another one for the layout code.

I have no really argument against this pattern, but I don´t know why it is necessary to defer some code of these phases to the next Frame. The execution of the Life Cycle methods could have been triggered also at the Render Event, then there would not have been any delay to another frame, even it still would add this nasty asynchrony.

So this pattern could make development easier but introduce asynchronous behavior where we lived in a beautiful synchronous Flash world before. In my opinion: Not a good trade.

What else?
Problems with reading out the measurements of DisplayObjects before they are rendered on screen

Remembering back to some of my Flash projects I have had sometimes strange problems with TextFields and measurement when setting text and using autosize. But I could not reproduce these problems in a test case anymore. So I am not sure if that was caused by some other stuff or maybe by differences in some older Flash Player versions? But at least in my situations these problems could always be solved without deferring code to another Frame. But at this point I am not sure if there are certain use cases where you cannot read out the size of a DisplayObject (TextField) before it is actually rendered to the screen. If there are such cases this would be a valid argument, but then I am wondering why this could not be solved on the Flash Player level instead of solving this problem at a Framework level.

And my last point:
Problems with complex execution flow from auto-layout containers code

I can imagine that complex situations with nested auto layout containers could be sometimes really tricky to handle. To avoid recursions or unnecessary calls for any possible situation in a generic framework is a tough challenge.

But also in complex situations it is a deterministic behavior, so it should be possible to solve this without the Life Cycle pattern as well. From my experience there was no problems with auto layout containers, but of course in normal project development you have limited use cases and we were not forced to deal with all the possible use cases, like Flex has to do as a generic framework.

So finally I don´t have any idea for the real reason why Adobe has introduced the Life Cycle.
Maybe it seemed that it could help solving a lot of tricky problems (auto layout containers, mixing MXML with AS code,…) and was considered as a good pattern to make development easier. Maybe the fact that Flash has a strong support for Event driven programming and the Flash developers are already used to handle this asynchrony, led to this decision?
Maybe is was a strategic decision to make Flex easier for new developers without Flash background, who were not familiar with the Flash Players frame-based execution model?

I don´t know. I really would appreciate if someone from the Flex Team could illuminate this topic.

I just have made the experience that many things where much more transparent, cleaner and faster in pure ActionScript then in Flex, and i think the Life Cycle is one of the reasons for that.
I really like the API of Flex but I am wondering why Adobe don´t give more attention to performance, specially for large scale applications.

Any comments or insights are highly appreciated!

P.S.: Just found an interesting post related to this. I 100% agree what Paul Taylor says about UIComponent, but that is another story. Ever heard about Reflex? Sounds pretty promising!

Comments (1)

Category: Actionscript,Flash,Flex,SDK