Skip to content

Manually Adding Injectors

TomByrne edited this page Jul 5, 2012 · 4 revisions

When using the @injectAdd/injectRemove metadata tags, the injector macro creates Injector objects, which contain the details of each injection. Sometimes it can be beneficial to create these objects manually, to customise the behaviour of Injectors further than the metadata tags allow.

Here is an example where the injector is told to pass through the ComposeGroup to which the found trait is attached. This can be useful when you need to access the found trait's siblings but it doesn't implement ITrait (and therefore doesn't offer an item property).

	class KeyboardShortcutManager extends AbstractTrait{

		private var shortcuts:Hash<IActionable>;
	
		public function new(msg:String){
			super();

			shortcuts = new Hash<IActionable>();
			
			var injector = new Injector(KeyboardShortcut, onShortcutAdded, onShortcutRemoved, false, true);
			injector.passThroughItem = true;
			addInjector(injector);
		}
	
		public function onShortcutAdded(trait:KeyboardShortcut, item:ComposeItem):Void{
			shortcuts.set(trait.shortcut, item.getTrait(IActionable));
		}
	
		public function onShortcutRemoved(trait:KeyboardShortcut, item:ComposeItem):Void{
			shortcuts.remove(trait.shortcut);
		}

	
		public function onKeyboardPressed(event:KeyboardEvent):Void{
			...
			var action:IActionable = shortcuts.get(pressedShortcut);
			action.performAction();
		}
	}
	
	class KeyboardShortcut{
		public var shortcut:String;
	}
	
	interface IActionable{
		public function performAction():Void;
	}

Using PropInjector

When the @inject metadata tag is used, the injector macro creates PropInjector objects which, like Injector objects, can be manually created for more control over injection.

In this example, a trait will seek out another trait only when it has a third sibling trait. It represents a policeman's AI, who is looking any character who has a weapon:

	class PoliceAI extends AbstractTrait{

		public var suspect:Person;

		public function new(msg:String){
			super();

			shortcuts = new Hash<IActionable>();
			
			var injector = new PropInjector(Person, this, "suspect", false, true);
			injector.additionalTraits = [Weapon];
			addInjector(injector);
		}
	}

Likewise, you could search for traits only when they don't have a particular sibling trait, using the unlessHasTraits property:

	class MedicAI extends AbstractTrait{

		public var suspect:Person;

		public function new(msg:String){
			super();

			shortcuts = new Hash<IActionable>();
			
			var injector = new PropInjector(Person, this, "suspect", false, true);
			injector.unlessHasTraits = [Weapon];
			addInjector(injector);
		}
	}