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.
Category: Actionscript,Flash,Flex,Performance
Published by Manfred Karrer on Thursday, 19 of January , 2012 at 02:38
With the heavily discussed announcement from Adobe about their commitment to Flex they crossed the line were it seems very likely that the Flash platform will not survive in the long term.
What Steve Jobs started, seems to be completed by Adobe themself.
This is somehow weird and bizarre because they own a technology which was incredible successful the last 12 years and is still the best solution for many kinds of Rich Internet Applications.
To just name a few reasons why I see Flash as such a strong platform:
- Nearly multi-platform technology. Ubiquitous penetration of the browser plugin + AIR (well I know: Steve Jobs left his marks….)
- Good development environment (language, tools, community, Flex framework…)
- Good performance and security model
- Easy and cheap to deliver good looking multimedia enabled user experience
Flash has set new standards and drove the internet forward (ok, I know ads are done with Flash as well…). Animation, multimedia, rich user interaction and the possibility to build desktop-like applications running in the browser are with Flash not a big deal. The rise of what Adobe coined Rich Internet Applications (RIA), were mainly driven by Flash/Flex.
I am not saying Flash is the best platform, and there are many things on my wish list and stuff to complain about. I also would prefer an open source technology following standards.
From a technology point of view there are many better solutions, like Director or the Java plugin were in the past much better then Flash but did not survive because of the low plugin penetration and the odd installation process. Flash was somehow the star for a long time and left the others behind, probably mainly because of the ease to install the plugin which leads to the high penetration rate of >98%. With Flex Adobe managed it to deliver a pretty good GUI framework and also attracted developers from more traditional languages like Java or C#.
The competitors like Silverlight, JavaFX or now HTML5 are seeming somehow (in the best case) like a copy and did not shine with much innovation.
Of course Flash is used in many places where it does not make sense, like for video or more complex web page navigation combined with HTML pages. So it is good that the modern browsers are able now to do this stuff directly without the indirection of a plugin. And of course it would be much better to have a browser being capable doing all kind of stuff directly which is done currently in Flash or with other plugins.
But why has this not happened in the last 15 years since browsers are prominent actors in the IT world?
Probably the biggest advantage of Flash was, that it bypassed the nasty problems with the incompatibility of the browsers and the slowness of innovation with the trick of using the plugin architecture to deliver a standard runtime for any browser and OS.
Like Java Flash can proudly proclaim: Write once, run everywhere!
And it looked great, was fast, was multimedia aware and made fun to play around. Concentrate the work on the application or game and not on dealing with browser compatibility problems.
With Actionscript (2,3) they set the foundation for a robust development environment. When you read about features of Googles Dart or some of Scala it somehow seems similar to that hybrid and well cooked mixture of Java and dynamic language features.
On this foundation it was possible to build large scale applications which were previously build as Java or C# desktop apps.
Why did companies move from the mature software development standards to something new and risky like Flash/Flex?
Because the apps looked good just out of the box, it was easy to develop and customize, multimedia was just a natural ingredient and it was more suitable for agile development models (rapid prototyping). At the end the costs were much lower as with a traditional software development process.
I think that was the main driver why RIAs became a success story. I think often the real reasons are pretty trivial.
Of course it is a benefit to have a browser based application available anywhere and the management of updates is much easier to handle. But the nature of RIAs is different to web pages. With an application you have a closer relation and there is no real barrier to install the app if it shows some real benefit to you. The success of mobile apps is proving that users have no problem to install an app they are using on a regular basis. If the way how to install it is easy, secure and free, the user does not mind the installation and even prefer the app model over the browser model (If you use twitter on your mobile, you use the app not the browser, right?).
What I want to say with this:
I do not believe the rise and success of RIAs came from the fact that the application is available on any computer via a browser, but more from other factors.
- The browser is recognized as trusted environment (no problems with security issues)
- The development costs are lower
- The maintenance costs are lower
- The User experience is often better (looks better)
With the decline of Flash/Flex I do not see yet any alternative technology which has the strength and market power of Flash.
The main problem with HTML5 I see in the politically motivated fragmentation of the browsers.
That seems even worse then 10 years ago. Back there was Microsoft against the rest. Now we have Google against Apple against Microsoft ignoring the rest.
They are all following totally different business targets with their browser concepts and I do not see any reasons why they should work better together in the future.
For me the problem with HTML5 is that you have to write code handling the differences of the most important browsers, so the main features works on all of them. Then you need to support some other browsers with a reduced feature set. And you need to test all versions in a very fast changing environment. That all comes with a poor language (Javascript is like Actionscript 1 12 years ago), a poor development environment and poor performance. I do not see any technological progress with this HTML5 hype. Flash 5 in 2000 was already more advanced (is the matching version number a coincidence?).
So in my opinion the only solution will be a technology which strongly supports multi-platform compilation.
Unity3D does this, haXe is doing this and openLaszlo did this partly already since 2004, as well as some other interesting moves in this direction (Joa Ebert). Adobe seemed to missed this trend.
The developer should not care about the output platform and concentrate to build applications without hacking to make it run in different environments.
Isn’t that the evolution of computer languages?
Machine code -> assembly -> C -> VM languages -> ?
Liberate the developer from the low level technical implementation and let him concentrate to the domain he is modeling in software. Writing hacks to make an application run on different browsers is against this evolution.
Of course writing multi-platform apps comes with some inherent problems. There are different capabilities, sizes, contexts and limitations to deal with, but they come naturally with the platforms and are not politically motivated hurdles created artificially by browser vendors.
I think the right candidate must be able to deliver an application for all major target platform without dealing with significant adoption problems and provide a modern, state of the art development environment (language, tools,…):
- Desktop (Win, Mac, Linux)
- Mobile/Tablet (Android, iOs)
- Web (Flash, HTML5)
- And maybe also Consoles or even Set-top boxes
This will define a new situation for the RIAs:
Assume you can develop an application for any platform, getting results which are close to native apps for this platform.
What are the benefits of RIAs when the Desktop app is much faster and has more capabilities?
Of course sometimes it makes sense to have the app, maybe as light or demo version, in the web for giving a lower entry barrier or to get a higher visibility. But in general the choice for the main platform will be much more derived from the nature and usage of the app then from external factors.
The stuff I use regularly I want to have as desktop or tablet app to get the best performance, security and feature set. If I need it to be mobile I install it as mobile app. Only the casual stuff will be a target candidate for the browser.
I do not think the browser will have the same importance in future like now (I know I am in opposition to Google with this). With a multi-platform compiler you can choose which platform matches best to your needs, and the browser will be reduced to that what it can do best. Displaying web pages and not imitating desktop applications.
I think sometimes ones success is more driven by the weakness of the others. Again pretty trial and no hot slogan for driving a hype.
Flash was successful because the browser vendors did (and still do) such a bad job in making a common standard and to being innovative.
The browser has been so successful because the OS vendors did a real bad job to not providing an easy and secure installation environment (the reason for Apples app store success). As well as not providing a native platform for cheap and easy software development (it is much easier to start with Flash or HTML then to write C code) and ignoring the importance and integration of the internet.
I guess in future there will be a multi-platform paradigm with focus on a main platform which makes most sense for the specific domain. The Desktop applications are looking somehow old as they have missed many important trends and can learn a lot from some successful RIAs. The RIAs which are imitating desktop apps will loose ground as with a multi-platform compiler there is no much motivation anymore not to deliver the better target platform.
Maybe I am all wrong with this. I know that I am against the current trends with these opinions, but i simply cannot see any real progress with this HTML5 hype and feel that there is a real need for something new.
Category: Actionscript,Flash,OffTopic,Software,Unity3D