Dawn
standing on the shoulders of giants
What is Dawn

• Dependency Injection library inspired by
  Google Guice
• Notification system based on types
• Simple type safe command pattern 
Why?

• Unhappy with my options
• Small issues that have large consequences
• Flash and Flex
• Small (~12K)
• A new breed of project
What its not

• MVC, MVP ... you structure your app
• Plugin architecture
• Aiming to take over the world
Some Design Principles
• Testing is vital
• Play to language strengths
• Type safety is winfull
• Configuration is no fun (keep it DRY)
• Static state is bad
• Types are better than strings
Dependency Injection
   a lot of fuss about nothing
TheDoctor
TheDoctor


  Tardis
TheDoctor


Assistant     Tardis
TheDoctor


Assistant     Tardis    Mission
TheDoctor


IAssistant     Tardis    IMission
TheDoctor


     IAssistant        Tardis    IMission



RoseTyler
        DonnaNoble
TheDoctor


     IAssistant        Tardis         IMission



RoseTyler                        Cybermen

        DonnaNoble                          Daleks
Object graph of
 TheDoctor

                          TheDoctor


          IAssistant        Tardis         IMission



     RoseTyler                        Cybermen

             DonnaNoble                          Daleks
Creating The Doctor
•   Construct dependencies within the class

•   Service locator

•   Factories

•   DI By hand
Doing it by hand
class TheDoctor{
  public var mission:IMission;
  public var assistant:IAssistant;
  public var tardis:Tardis;
}
Doing it by hand
var doctor:TheDoctor = new TheDoctor();
Doing it by hand
var tardis:Tardis = new Tardis();
var doctor:TheDoctor = new TheDoctor();
doctor.tardis = tardis;
Doing it by hand
var assistant:IAssistant = new RoseTyler();
var tardis:Tardis = new Tardis();
var doctor:TheDoctor = new TheDoctor();
doctor.tardis = tardis;
doctor.assistant = assistant;
Doing it by hand
var mission:IMission = new Daleks();
var assistant:IAssistant = new RoseTyler();
var tardis:Tardis = new Tardis();
var doctor:TheDoctor = new TheDoctor();
doctor.tardis = tardis;
doctor.assistant = assistant;
doctor.mission = mission;
Doing it by hand
•   Thats a lot of code to create a Doctor

•   More code to maintain

•   Fragile to change

•   Client of TheDoctor must know inner workings
    (encapsulation fail)

•   Construction followed simple patterns
Dependency Injection
 is all about creating
    object graphs!
Dawn DI
•   How can object creation be automated and easy?

•   Meets design principles

•   Thank you Google Guice!
Configure the Doctor
Configure the Doctor
1. Indicate the dependencies
Configure the Doctor
1. Indicate the dependencies

2. Chose an assistant
Configure the Doctor
1. Indicate the dependencies

2. Chose an assistant

3. Chose a mission
Configure the Doctor
class TheDoctor{
  public var mission:IMission;
  public var assistant:IAssistant;
  public var tardis:Tardis;
}
Configure the Doctor
class TheDoctor{
  [Inject] public var mission:IMission;
  [Inject] public var assistant:IAssistant;
  [Inject] public var tardis:Tardis;
}
Configure the Doctor
class Config implements IConfig{
   public function create(mapper:IMapper):void{
      mapper.map(IAssistant).toClass(RoseTyler);
      mapper.map(IMission).toClass(Daleks);
   }
}
Create the Doc
var mission:IMission = new Daleks();
var assistant:IAssistant = new RoseTyler();
var tardis:Tardis = new Tardis();
var doctor:TheDoctor = new TheDoctor();
doctor.tardis = tardis;
doctor.assistant = assistant;
doctor.mission = mission;
Create the Doc
Create the Doc


builder.getObject(TheDoctor)
Create the Doc

var doctor:TheDoctor;
var builder:IBuilder = new Builder(new Config());

doctor = builder.getObject(TheDoctor) as TheDoctor;
Dawn DI
•   You write less code (no XML)

•   Configuration is ActionScript (and small)

•   Classes are compiled into final swf

•   Agile code, refactor structure fast and easily

•   Testing is easy, second nature

•   DI helps you write better code!

•   Dawn makes DI easy!
Dawn DI
•   Scopes - Singleton or Transient

•   Map toFactory/toInstance for construction control

•   Modular configuration

•   Name injections

•   Inject properties like strings or arrays

•   Optional injections

•   Inject via mutators or properties
FP-183
[Inject] Dawn DI
•   Simple

•   Light

•   Type safe

•   Test friendly

•   Terse
Notifications
decoupling without the compromise
Dawn Notifications

•   Type based

•   Closure friendly

•   Static free
The Problem
The Problem
View


View


View


View
The Problem
View


View
            Data

View


View
The Problem
View


View
            Data
            Data
View


View
The Problem
View


View
            Data
            Data
             Data
View


View
The Problem
View


View
            Data
            Data
             Data
              Data
View


View
The Problem
View


View
            Data
            Data
             Data
              Data
View


View
The Problem
View


View
            Data
            Data
             Data
              Data
View


View
The Problem
View


View
            Data
            Data
             Data
              Data
View


View
The Problem
View


View
            Data
            Data
             Data
              Data
View


View
The Problem
View


View
            Data
            Data
             Data
              Data
View


View
The Problem
View


View
            Data
            Data
             Data
              Data
View


View
The Problem
View


View
            Data
            Data
             Data
              Data
View


View
The Problem
View


View
            Data
            Data
             Data
              Data
View


View
The Problem
View


View
            Data
            Data
             Data
              Data
View


View
The Problem
       Gets a little confusing?
View


View
                 Data
                 Data
                  Data
                   Data
View


View
Decouple and Scale
Decouple and Scale
View


View


View


View
Decouple and Scale
View


View

             Data
             Data
              Data
               Data
View


View
Decouple and Scale
         Notification System
View


View

                    Data
                    Data
                     Data
                      Data
View


View
Decouple and Scale
         Notification System
View


View

                    Data
                    Data
                     Data
                      Data
View


View
Decouple and Scale
         Notification System
View


View

                    Data
                    Data
                     Data
                      Data
View


View
Type based
Type based


addEventListener(type:String,closure:Function...)
Type based


addEventListener(type:String,closure:Function...)

   addCallback(type:Class,closure:Function);
Why Types
Why Types
•   Make full use of polymorphism
    IEventType, BaseRpcEvent, com.wibble.Woo
Why Types
•   Make full use of polymorphism
    IEventType, BaseRpcEvent, com.wibble.Woo

•   Avoids meaningless statics
    FinishedBaconEvent.FINISHED_BACON
Why Types
•   Make full use of polymorphism
    IEventType, BaseRpcEvent, com.wibble.Woo

•   Avoids meaningless statics
    FinishedBaconEvent.FINISHED_BACON

•   No hidden collisions
    MyEvent.CLOSE == Event.CLOSE == FAIL
Why Types
•   Make full use of polymorphism
    IEventType, BaseRpcEvent, com.wibble.Woo

•   Avoids meaningless statics
    FinishedBaconEvent.FINISHED_BACON

•   No hidden collisions
    MyEvent.CLOSE == Event.CLOSE == FAIL

•   No switch statements
    switch( notification.getName() )
Closure unfriendly

addEventListener(Event.ADDED,
   function(event:Event):void{
       trace(“haha, Try removing me”)
   });
Closure friendly!
Closure friendly!

var listener:IListenerRegistration =
   bus.addCallback(ILogAction,
       function(note:ILogAction):void{
       }
   );
Closure friendly!

var listener:IListenerRegistration =
   bus.addCallback(ILogAction,
       function(note:ILogAction):void{
       }
   );

listener.remove();
Triggering
class TadPole{
     [Inject] public var bus:INotificationBus;

    [DependenciesInjected]
    public function init():void{
      bus.trigger(new TadPoleCreated());
    }
}
Dawn Notifications
•   Simple API

•   Use the language, closures are good!

•   Types are smarter then strings (Duh!)

•   Reduce the complexity of application structure
Commands
simple tools are easy to build with
Commands
• easy to maintain stateless goodies
• central point for lots of easy wins
 • queueing
 • cacheing
 • handle errors
 • etc etc.
Commands
• ICommand interfaces force casting
 •   execute(param:Object):void

• How to access other application objects
 •   Model.getInstance();

• Mapping Strings to Commands is fiddly
  (more developer discipline)
 •   registerCommand(Notify.GET_THING, GetThingCommand);
Dawn Commands

• Injectable
• Type safe
• Type based DRY configuration
Dawn Commands
class MakeHayCommand{
      [Inject] public var barn:Barn;


     [Execute] public function execute(note:MakeHay):void{
        barn.makeHay(note.howMuchHay);
     }
}
Dawn Commands
class MakeHayCommand{
    [Inject] public var barn:Barn;


     [Execute] public function execute(note:MakeHay):void{
       barn.makeHay(note.howMuchHay);
     }
}
Dawn Commands
class MakeHayCommand{
      [Inject] public var barn:Barn;


    [Execute] public function execute(note:MakeHay):void{
       barn.makeHay(note.howMuchHay);
    }
}
Dawn Commands
class MakeHayCommand{
      [Inject] public var barn:Barn;


     [Execute] public function execute(note:MakeHay):void{
        barn.makeHay(note.howMuchHay);
     }
}
Dawn Commands



 addCommand(MakeHayCommand);
Dawn

• Dependency Injection
• Notifications
• Commands
http://github.com/
  sammyt/dawn
Questions etc?

Dawn - Actionscript Library