Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

finished readme

  • Loading branch information...
commit 390f42c38546f70426772e35b9d51b2e2143500d 1 parent 959ef16
@seanhess authored
View
BIN  .README.mdown.swp
Binary file not shown
View
3  .gitignore
@@ -8,4 +8,5 @@ bin-debug
html-template
.flexProperties
sandbox
-Sandbox*
+Sandbox*
+*.swp
View
31 GOALS.mdown
@@ -0,0 +1,31 @@
+# Zero
+
+Dependency Injection Framework for Actionscript
+
+### Goals
+
+1. To allow classes to "implement" interfaces in pieces
+2. To make overriding by decoration simple
+3. Make it easy to create short-term objects (Injecting factories)
+4. Testing and Local Mocking should be easy
+5. To make it configurable at runtime, including the ability to disconnect
+6. To allow different implementations based on context
+7. Beautiful syntax in both MXML and AS
+8. Easy to override functionality of the core
+
+### Use Cases
+
+* When testing, pass in mock implementations to a class
+* Switch to a mock server connection at runtime (a checkbox)
+* 4 different views of a list of users. Invisible ones are inactive and don't receive updates
+* When a module is unloaded it is deactivated and GC'd
+* Give a particular view a unique implementation
+* Give a particular class a unique implementation
+* Give a set of views/classes a unique implementation
+* Proxy all service requests, to convert xml data to strongly typed data before returning
+* Log all requests in the system without requiring the implementations to know about it
+
+
+
+
+
View
301 README.mdown
@@ -1,38 +1,299 @@
# Zero
-Dependency Injection Framework for Actionscript
+Zero is a new way to approach Dependency Injection in Actionscript. It is a toolkit that replaces the concept of the Interface with the DependencyInterface, which define an interface using Decorators instead of an actual Interface. This offers several advantages.
-## Goals
+Here are the goals of the project.
-1. To allow classes to "implement" interfaces in pieces
-2. To make overriding by decoration simple
-3. Make it easy to create short-term objects (Injecting factories)
-4. Testing and Local Mocking should be easy
-5. To make it configurable at runtime, including the ability to disconnect
-6. To allow different implementations based on context
-7. Beautiful syntax in both MXML and AS
-8. Easy to override functionality of the core
+1. Implement some or all of an interface with one or more classes
+2. Override funcitonality with anonymous Decorators
+3. Create short term dependencies with a clear Factory pattern
+4. Testing and Mocking are as simple as with normal interfaces
+5. Configure implementations at runtime
+6. Disconnect a client from implementations
+7. Change implementations based on context
+8. Clean configuration in both AS and MXML
+9. Easily modifiable core functionality.
-## Use Cases
+### Getting Started
-#### When testing, pass in mock implementations to a class
+Visit Downloads and get the latest swc.
-Switch to a mock server connection at runtime (a checkbox)
+ Short Example
-4 different views of a list of users. Invisible ones are inactive and don't receive updates
+### Contribute
-When a module is unloaded it is deactivated and GC'd
+Zero is open source
-Give a particular view a unique implementation
+http://github.com/seanhess/zero
-Give a particular class a unique implementation
+### DependencyInterfaces
-Give a set of views/classes a unique implementation
+Instead of a normal AS Interface, you create a simple class that defines an interface. By defining functions, you create strong-typing.
-Proxy all service requests, to convert xml data to strongly typed data before returning
+ public function doSomething(param:String):Boolean { return i.doSomething(param) }
-Log all requests in the system without requiring the implementations to know about it
+You can also define getters and setters
+
+ [Bindable]
+ public function set name(value:String):void { i.name = value }
+ public function get name():String { return i.name }
+Here is a full example
+
+ package dependency
+ {
+ public class DLibrary extends DependencyInterface
+ {
+ /**
+ * Passing the context to the constructor is required
+ */
+ public function DLibrary(context:*) { super(context)}
+
+ public function get books():IList { return i.books }
+
+ public function addBook(title:String):void { i.addBook(title) }
+ }
+ }
+
+You can use "arguments" to simplify passing the arguments along
+
+ public function manyArguments(one:SomeClass, two:String, three:int):void { i.manyArguments(arguments) }
+
+### Using Dependencies
+
+You use the "new" operator anywhere as if you were creating the class. Zero takes care of the rest.
+
+ // "this" is the context
+ var library:DLibrary = new DLibrary(this);
+
+Don't worry, you are _not_ creating a dependency on the implementation. Think of the DependencyInterface as a normal AS Interface. DependencyInterfaces are easy to refactor to Interfaces and vice versa.
+
+You can create them in MXML as well.
+
+ <!-- Automatically sets the context -->
+ <dependency:DLibrary/>
+
+### Implementations
+
+There are no constraints on implementations at all. You don't have to implement all the functions.
+
+ package service
+ {
+ public class Library
+ {
+ /**
+ * books is immutable because the interface only defines
+ * a getter
+ */
+ public var books:IList = new ArrayCollection();
+
+ public function addBook(title:String):void
+ {
+ books.addItem(title);
+ trace("Added " + title + " to library");
+ }
+ }
+ }
+
+### Connceting Implementations
+
+You can easily specify the implementation for an interface in Actionscript.
+
+ import dependency.DLibrary;
+ import service.Library;
+
+ var connect:Connect = new Connect(this);
+ connect.add(new Implement(DLibrary, Library));
+
+You can do it in MXML as well
+
+ <zero:Connect>
+ <zero:Implement dependency="{DLibrary}" factory="{Library}"/>
+ </zero:Connect>
+
+### Multiple Implementations
+
+A single class doesn't need to be responsible for the whole interface.
+
+ package service
+ {
+ public class Books
+ {
+ public var books:IList;
+ }
+ }
+
+ package service
+ {
+ public class BookCreator
+ {
+ public function addBook(title:String):void
+ {
+ trace("Do something different");
+ }
+ }
+ }
+
+You can then connect both of them to the interface. Later implementations have priority.
+
+ var connect:Connect = new Connect(this);
+ connect.add(new Implement(DLibrary, Books));
+ connect.add(new Implement(DLibrary, BookCreator));
+
+or in MXML
+
+ <zero:Connect>
+ <zero:Implement dependency="{DLibrary}" factory="{Books}"/>
+ <zero:Implement dependency="{DLibrary}" factory="{BookCreator}"/>
+ </zero:Connect>
+
+### Factories
+
+You can define factories for short-term objects, like value objects or models.
+
+ // interface
+ public class DBook extends DependencyInterface
+ {
+ public function get title():String { return i.title }
+ public function set title(value:String):void { i.title = value }
+ }
+
+ // implementation
+ public class Book
+ {
+ public var title:String
+ }
+
+And you tell Zero to connect them like this
+
+ connect.add(new Factory(DBook, Book));
+
+or in mxml
+
+ <zero:Connect>
+ <zero:Factory dependency="{DLibrary}" factory="{BookCreator}"/>
+ </zero:Connect>
+
+You can then use the "new" operator, like normal, but Zero creates a new instance every time.
+
+ var book:DBook = new DBook(this);
+
+or in mxml
+
+ <dependency:Book title="here is a title"/>
+
+### Proxying
+
+Even more powerfully, you can define Proxies to intercept implementations
+
+ public class LibraryProxy extends ObjectProxy
+ {
+ public function addBook(title:String):void
+ {
+ trace("Do something cool");
+ object.addBook(title);
+ trace("Do something even cooler!");
+ }
+ }
+
+They are connected like normal
+
+ var connect:Connect = new Connect(this);
+ connect.add(new Implement(DLibrary, Library));
+ connect.add(new Proxy(DLibrary, LibraryProxy));
+
+### Dependencies in Implementations
+
+Any class can ask for a dependency. Here's our Library example revisited, using the DBook factory
+
+ public class Library
+ {
+ /**
+ * books is immutable because the interface only defines
+ * a getter
+ */
+ public var books:IList = new ArrayCollection();
+
+ public function addBook(title:String):void
+ {
+ var book:DBook = new DBook(this);
+ book.title = title;
+
+ books.addItem(book);
+ trace("Added " + title + " to library");
+ }
+ }
+
+### Testing and Mocking
+
+Dependencies will not connect unless you specify a context. You can deliberately skip that step, and pass in your own.
+
+ var library:DLibrary = new DLibrary(); // I left out the context!
+ library.implementation = new MockLibrary();
+
+You can also connect an implementation by package or class instead. (see below)
+
+### Disconnecting an Interface
+
+You can disconnect an interface by calling its `disconnect` method.
+
+ library.disconnect();
+
+And reconnect it with `connect`
+
+ library.connect();
+
+### Disconnecting a View
+
+You can disconnect an entire context
+
+ var connect:Connect = new Connect(this);
+
+ // disconnects everything inside this context
+ connect.disconnect();
+
+ // disconnects some other context
+ connect.disconnect(someOtherObject);
+
+ // disconnects every context that matches the pattern
+ connect.disconnect("view.*");
+
+### Implementation by View
+
+You can specify a different implementation for everything within a particular view by putting new connect instructions in it.
+
+ <!-- MainApplication.mxml -->
+ <zero:Connect>
+ <Implement dependency="{DLibrary}" factory="{Library}"/>
+ </zero:Connect>
+
+ <!-- SomeOtherView.mxml -->
+ <zero:Connect>
+ <Implement dependency="{DLibrary}" factory="{ADifferentLibrary}"/>
+ </zero:Connect>
+
+### Implementation by Other Context
+
+The same applies for any context, actually, just define the connect instance with the other class as the instance.
+
+ var connect:Connect = new Connect(someOtherContext);
+ connect.add(...);
+
+### Implementation by Class
+
+You can pass a class into Connect instead of a reference
+
+ import view.SomeView;
+
+ var connect:Connect = new Connect(SomeView);
+ connect.add(...);
+
+### Implementation by Package
+
+You can pass in a string with wildcards too.
+
+ var connect:Connect = new Connect("view.admin.*");
+ connect.add(...);
Please sign in to comment.
Something went wrong with that request. Please try again.