Posts Tagged → dawn
The fussy type
Recently I have been creating a lot more libraries for the flash player that rely on reflection, dawn being one of those. I found that my reflection requirements where not easily met with the current tools, and so, Fussy was born!
Love it or hate it describeType is the only (almost) way to preform reflection on types in actionscript, it returns a XML document containing information about a type in one big dump! There are a number of excellent and proven libraries out their that can convert that XML dump into a nice OO data structure for you to code against, and it crossed my mind several times while developing dawn that they could make my life a lot easier. I however, created another reflection library… what was I thinking!?
Thing is, I have never needed a full strongly typed objected orientated representation of my type! That would be nice of course, but when I turn to reflection its not to create Method and Parameter objects (I’d rather the runtime did that to be honest) its because there are specific things about a type that I need to find.
A simple example of what I need reflection for in dawn would be to find all the methods in a type that have been decorated with the [Inject] metadata and have one or more arguments. i.e. all the injectable methods for a Class. Whether the reflection API gives me a XML document or the same information parsed into types I’m still going to have develop a way of finding all the methods with Inject metadata. Maybe that will be with e4x or maybe a loop over some objects (perhaps ensuring that they are methods not variables/accessors), then I will need to check that those methods have some arguments and are thus injectable. So whatever the means the types reflection information is provided by, the actual logic of my task is entirely up to me to develop and test.
With all that in mind, I built Fussy to be a little different from current reflection libraries (at least those that I know of). I wanted something to help me query my types, where the query represented whatever I wanted to find out about my types. To show you what I mean by “query”, lets see how fussy allows me to find the injectable methods on a type (the problem from above)
Start by creating a fussy
var fussy:Fussy = new Fussy()
Now to describe my query
var query:IQuery = fussy.query().findMethods().withMetadata("Inject").withArguments();
Now I can execute that query against any type, and get a array of strongly types Method objects
var methods:Array = query.forType(MyClass);
And TA DA! I have strongly typed method objects that satisfy my query for MyClass.
So what is Fussy?
Seems quite late in this post to be asking that, but I figured it would be easier to explain after an example. I call fussy an actionscript reflection query language. It does of course perform reflection, and parse the result of that reflection into strongly typed objects (only after a query has run) but the main aim of fussy was to make the logic of reflection (the reason why I was reflecting in the first place) easier as faster.
Fussy is a work in progress, I still think I can make the query API more elegant and there are lots more query extensions I can think of to add but its already pretty useful. It now supplies dawn with all its reflection needs, and what was a huge proportion of dawns code (searching and parsing types) base has been reduced down to one class.
Got lots more plans for Fussy, including things like metadata schema validation. I find its pretty useful, so figured someone else might too.
Oh, here is the github link
Similar, but different! Private Configurations
I’ve just added another feature to the development branch of dawn, called private configurations. So, what are they, and why did I bother?
When I first demoed Dawns injector in a LBi tech talk (almost a year ago now) one clever chap asked how it could be used to create a number of very similar, but different objects graphs. I only half got my head around the question at the time, and blurted out something about named injections. Then sometime (and some beers) later after discussing the problem more it became clear that Dawn didn’t really have a very elegant solution to the problem.
Time to explain the problem (if you’ve heard of the robot leg problem, thats the one!). How can I create two similar object graphs, with some defined differences without having to create new concrete classes to represent those different graphs (thats what you would have todo today btw)? Example time.
Picture a Car class (or just read the one below)
class Car {
var engine:Engine;
var transmission:Transmission;
var driveLine:IDriveLine;
public function Car(engine:Engine, transmission:Transmission, driveLine:IDriveLine) {
// set properties etc //
}
}
Engine and Transmission are base classes that have a number of subclasses like PetrolEngine, DieselEngine, AutomaticTransmission and ManualTransmission. IDriveLine is an interface for the various type of drive the car could have, FrontWheel, RearWheel or FourWheel etc.
The Car class itself is pretty flexible (polymorphism is handy like that), depending on how we construct the car we could get a four wheel drive diesel or an manual transmission, rear wheel drive etc. In Dawn today you could create a configuration for your Car and install it into the injector.
class CarConfig implements IConfiguration {
public function configure(mapper:IMapper):void {
mapper.map(Engine).to(PetrolEngine);
mapper.map(Transmission).to(ManualTransmission);
mapper.map(IDriveLine).to(RearWheel);
}
}
// then where you create your injector
injector.install(new CarConfig());
Using the above code, every time you requested for a Car from the injector it would create one with a petrol engine, rear wheel drive and manual transmission. *Every Time* is not what we want though! Without private configurations we would have to find a way round this, most likely by creating subclasses of Car, such as PetrolCar, which had a constructor parameter of type PetrolEngine, then the same for RearWheelDriveCar, and so on, until we had classes to represent the varieties of object graphs we wanted.
Private configurations are a port of Guices solution (private modules) to the same problem. They allow you to create groups of mappings that are only available under certain conditions.
Here are a couple of private configurations for the above problem
class SportyCarConfig implements IPrivateConfiguration {
public function configure(mapper:IPrivateMapper):void {
mapper.map(Engine).to(PetrolEngine);
mapper.map(Transmission).to(ManualTransmission);
mapper.map(IDriveLine).to(RearWheel);
mapper.expose(Car, "Sporty");
}
}
class ChelseaTractorConfig implements IPrivateConfiguration {
public function configure(mapper:IPrivateMapper):void {
mapper.map(Engine).to(DieselEngine);
mapper.map(Transmission).to(AutomaticTransmission);
mapper.map(IDriveLine).to(FourWheel);
mapper.expose(Car, "4x4");
mapper.expose(Showroom, "SUV Land");
}
}
If the two configurations above were just normal configurations we would have a little problem when we installed then into the injector, since they both create mappings for the same types. So the second configuration to be installed would overwrite the first ones mappings for Engine etc. Also notice that both the private configurations make one or more calls to an *expose* method.
Installing private configurations is almost identically to installing normal ones:
var injector:IInjector = Injector.createInjector(); injector.installPrivate(new ChelseaTractorConfig()); injector.installPrivate(new SportyCarConfig());
Installed private configurations do not overwrite mappings within other normal configurations or private configurations. So when we install the SportyCarConfig we have not overwritten the settings in the ChelseaTractorConfig. But how then do we create a car that uses either one of those configurations? Well thats what the expose method is all about! Private configurations are private (hidden) until a special exposed mapping is requested from the injector. Once the exposed mapping is requested the mappings within the private configuration become public, and take precedence over any configurations that already exist in the injector.
Lets expand the above code snippet a little to add some default mappings for the IDriveLine, Engine and Transmission.
var injector:IInjector = Injector.createInjector(); // add default normal car mappings injector.map(IDriveLine).to(FrontWheel); injector.map(Engine).to(PetrolEngine); injector.map(Transmission).to(ManualTransmission); // install the private configurations injector.installPrivate(new ChelseaTractorConfig()); injector.installPrivate(new SportyCarConfig());
Now if we request a Car from the injector (injector.inject(Car)) we will get the default options:
var car:Car = Car(injector.inject(Car)); trace(car.engine is PetrolEngine) // true trace(car.driveLine is FrontWheel) // true trace(car.transmission is ManualTransmission) // true
To activate a private configuration we must request one of the exposed mappings. Ok, lets create a sporty car.
var sportyCar:Car = Car(injector.inject(Car, "Sporty")); trace(sportyCar.engine is PetrolEngine) // true trace(sportyCar.driveLine is RearWheel) // true trace(sportyCar.transmission is ManualTransmission) // true
This time when we asked the injector for a Car we specified the name of the mapping, Sporty. When the injector sees that we are requesting a mapping of type Car named Sporty, it activates the SportyCarConfig, since that is the *exposed* mapping of the configuration! It doesn’t matter that the configuration does not supply a mapping for those options (type Car, named Sporty), it just knows that thats the mapping that unlocks it.
Now we can create a four wheel drive car
var bigCar:Car = Car(injector.inject(Car, "4x4")); trace(bigCar.engine is DieselEngine) // true trace(bigCar.driveLine is FourWheel) // true trace(bigCar.transmission is AutomaticTransmission) // true
This time we requested a mapping of type Car named 4×4, which is one of the exposed mappings that activates the ChelseaTractorConfig, so the car we get is provisioned with the mappings found in the ChelseaTractorConfig over the default ones.
And that in a nutshell is what private configurations are all about. They are a terse and clean way to separate configurations for object graphs which can be activated by special exposed mappings.
This is all tested and committed to the dev branch of Dawn awaiting inclusion in the next release
dawn injectors multi-mappings
I just added a new feature to the dev branch of dawn, and since I haven’t got changelog files yet (bad sammy!!) I figured I would throw a post up so it doesn’t get lost. Seriously though, there will be a changelog
This feature will make the next version of dawn, unless someone convinces me its bonkers.
I am aiming for dawns injector to be a complete injection solution (shiny bells AND whistles!!). Its not doing bad, but there are a few places that some polish wouldn’t hurt (better error reporting is a big on one those, its on the way).
This latest change was born out of a request from Mr. Tink. He wanted to be able to map one class (in singleton scope) to two interfaces. While such an exciting feat was possible previously, it really required knowledge of factory providers (and consequently some custom code). The new solution is much neater and is as simple as pie… I hope, O.K. an example:
Lets say I have a model object that implements a simple interface for views (or mediators or whatever said framework fancies). Simple, except that I also want methods on the object that shouldn’t be exposed to the view objects, so those can be added to an interface that extends the original one with the extra functionality.
// for dumb clients things like views etc
interface IAccessData {
function getMyThing():Thing;
}
// for services/commands etc
interface IChangeData extends IAccessData {
function updateMyThing(wibble:Wibble):void;
}
class ThingModel implements IChangeData { ... }
ThingModel implements both of these interfaces, and I only want one of my models to be created and that same instance to be injected for anything that require either IChangeData or IAccessData.
Previously I would have either had to map to a factory or an instance twice to get this to work, i.e.
// pray it has no constructor dependencies var myModel:ThingModel = new ThingModel(); injector.map(IAccessData).toInstance(myModel); injector.map(IChangeData).toInstance(myModel);
or
injector.map(IAccessData).toFactory(ThingModelFactory);
injector.map(IChangeData).toFactory(ThingModelFactory);
class ThingModelFactory { ... blah ... }
Either way, I have to create two mappings and its not so fun. If there was a third interface, or I wanted to also map the concrete class to the same instance it would require a third mapping.
In the next version of dawn (already in the dev branch) we can just do this
injector.map(IAccessData).and(IChangeData).to(ThingModel).asSingleton();
Ta Da!!
Much easier. Under the hood dawn still creates two mappings, its just sugar coated with the mapping DSL and our lovely ‘and’
Its also “chainable” (is that a word? I doubt it).. so if I also wanted classes that depend on the concrete implementation of ThingModel to get the same instance, I could just add another ‘and’
injector.map(IAccessData).and(IChangeData).and(ThingModel).to(ThingModel).asSingleton();
And there you have it, multi-mapping goodness. There are lots of other things coming soon, I just needed to get that one off my chest.
Also worth checking out is the asEagerSinglton scope that just made it into 0.8
commanding dawn
Over the last few weeks I have been trying to improve the documentation for Dawn on its GitHub page. I am slowly making progress (hindered a little by starting a new job) but realise there are still some real weak spots. One area in particular is Dawn’s use of the command pattern. I built Dawn’s commands in a bit of a rush while completing the project that demonstrated the need for them, so have held back giving them too much formal documentation until I can clean them up and add a couple more key features. That said, I still find them very useful in their current state so thought I’d write this little post to give them more of an airing.
There are lots of good reasons for using commands in your applications. They are a proven solutuion for all sorts of common problems in client side development such as queueing, cacheing, batching etc. They are also very useful for performing business logic that spans multiple domains within an application, and thus belong in no one domain alone.
Why make another command library?
Enough of why commands are good (we all know that), why does Dawn contain its own flavour of this oh so common pattern? In turns out providing the command pattern is not a simple as it might seem in Actionscript, at least not if you have some design principles you intend to stick to. Most of the frameworks I have come accross in actionscript provide commands in a pretty similar way, the steps are somethings like this
- Create a new object that implements some ICommand interface
- implement the execute method, which takes some generic object as its argument. Find a way to get hold of any objects you need, perhaps a service locator (PureMVC) or a singleton (Caringorm)
- define some string or event (a string type field) that triggers the command
- configure the framework to trigger the command on the newly defined event (one-to-one mapping)
So what is wrong with that? How could that be better? It seems to me that those steps break a number of principles I think are fairly important, it also looks like a lot of work which could go wrong.
Take step 1. “Create a new object that implements some ICommand interface“. Everyone loves a bit of programming to interfaces! But there a snag here with Actionscript, that ICommand interface will have defined a type for its argument e.g.
interface ICommand{
function execute(event:FrameworkEvent):void
}
In actionscript there is no way for me to extend an interface and narrow the type of the argument, this for example would be impossible
interface MyCommand extends ICommand{
function execute(event:MyFrameworkEvent):void
}
What that means is that any commands I write that want to get information out of the event that triggered them are going to have to cast the argument! Type safety FAIL! I want to be able to write type safe commands that know the exact type of their arguments.
Step 2. “implement the execute method, which takes some generic object as its argument. Find a way to get hold of any objects you need, perhaps a service locator (PureMVC) or a singleton (Caringorm)” You can probably guess what I dont like about that. Commands are so valuable because they can encapsulate complex logic that involves a number of parts of an application. But commands are stateless (created each time they are executed) and tend to be created by the framework, so how can they get hold of the objects that they need to act upon? In most frameworks I have come across objects that need to be involved in commands either need to implement the singleton pattern – the enemy of testable code! Or register with a service locator, which adds new dependencies on the command to a service locator class and a random string against which the object may (fingers crossed) be registered against. I want my commands to have as few dependencies as possible, I dont want to have to rely on strings to get hold of the core actors in my system, and I certainly dont want to fall into the many traps thats singletons lay.
step 3. “define some string or event (a string type field) that triggers the command” Having created this command in framework X I now need to think about how to trigger its execution. I might have to create a new object that extends some base event to do this, or I may just have to choose a string name. I can just about deal with this step, I know that there is going to have to be something that triggers the command (I just dont think string or events are very good choices).
step 4. “configure the framework to trigger the command on the newly defined event (one-to-one mapping)” This is where the previous step starts to frustrate me. I have to TELL the framework that the object I just created is the one that will trigger the command. This will most likely look something like so
framework.registerCommand( MyThing.NAME, MyLovelyCommand );
There are a couple of things I don’t like about that, firstly it depends on developer discipline (I dont have that!), meaning it’s up to me to check that the value of MyThing.NAME is what it should be, the compiler won’t care if all my NAME properties have the same value!! Secondly it’s configuration, and configuration does not rock my boat.
how is Dawn different?
Heres an example of what a typical command might look like in Dawn (in a typical hay making application).
class MakeHayCommand{
[Inject] public var barn:Barn;
[Execute] public function execute( note:MakeHay ):void{
barn.makeHay(note.howMuchHay);
}
}
There are a few things to note
- there is no ICommand interface
- the argument to the execute method is specific to the business logic being executed
- the execute method has [Execute] metadata
- the barn variable has [Inject] metadata
You might have already guessed that a Dawn command was not going to implement an ICommand interface. Dawn tries to make the most of Actionscript by using metadata over interfaces here inorder to preserve type safety. When this command is triggered the method that has the [Execute] metadata will be invoked (this also means that we could call the method anything we like, something more meaningful, like, makeTheHay). Now that we have an argument that is specific to the business logic being executed we no longer need to perform risky runtime casting.
My other major gripe with commands is how core actors within a system are reached, Dawn makes this easy by building upon its dependency injection library. Just like any other object in Dawn, the command need only specify what it needs by providing the [Inject] metadata. Dawn will ensure that the relavent objects are constructed/retrieved before the command is executed, so all the logic to fetch domain objects via service locators or singletons is removed, making for a terser more testable command.
While all that type safety would be good on its own it also hands us another easy win with a bit of dry configuration. We (and Dawn) can see the type of the argument of the execute method, so we can completely skip the configuration step (thats the nasty bit where we start defining strings all over the place), the command is implicitly mapped to the MakeHay notification.
Setting up and triggering a command then looks much simpler
We tell Dawn we have a new command (but skip any mapping step)
commands.addCommand(MayHayCommand);
Since the command system is built on top of Dawns other libraries (DI and notifications) we can just send a notification of type MakeHay to trigger the command.
notificationBus.trigger(new MakeHay(numberOfBales));
and we’re done.
One more quick win
Another nice feature we get for free by building on top of the notification system is that any command you write is mapped by type, and types can be concrete classes (like the above example) or abstract classes or even interfaces.
Here is a command that will log any notification that implements IResponder
class LogRpcCommand {
[Execute] public function execute( responder:mx.rpc.IResponder ):void {
trace("making rpc call", responder);
}
}
Recap
Hopefully I’ve gone someway in justifying why Dawn implements it’s own command pattern. I wanted to ensure my code stayed type safe, I didn’t want to invent verbose ways of getting hold of objects within the system, and I didn’t want to map classes to string.
I still have someway to go with them, there is more I want from them (queueing baked in etc) but I already find them very useful, and well worth their place in Dawn.
Dawn at FLUG
Last night I got the chance to give Dawn its public launch as I presented it at FLUG. Dawn is a set of libraries I have been developing to aid my actionscript development. It consists of three core parts
- A dependency injection library inspired by Google Guice
- A notification system based on types
- A simple type safe command pattern
I built Dawn to address a number of issues that I felt existed in many of the current approaches to application development for the Flash platform. I hope I went some way to demonstrating how I feel Dawn helps you write testable, type safe and agile code.
Thanks to all who attended and for the the positive feedback.
Below are the slides I used in the talk, or you can download the keynote file