Code Monkey home page Code Monkey logo

swiftsuspenders's Introduction

SwiftSuspenders

Attention: This README is just a stub to prevent you from reading the heavily outdated one for Swiftsuspenders 1.x.

That being said, here's a very quick outline of the new version's capabilities and API:

Features

  • injection requests configurable using standardized metadata
  • can inject into vars, setters, methods and constructors
  • injection requests can be optional
  • mapping dependencies by class and, optionally, name
  • satisfying dependencies using value, class instance, singleton or custom providers
  • chaining multiple injectors to create modular dependency-mapping graphs much like inheritance works in OOP
  • defining local and shared scope for mappings, akin to public and private members of a class
  • defining soft mappings that only get used if no injector higher up in the inheritance chain can satisfy a dependency
  • support object live-cycle management (note: The latter part of that management, i.e. the destruction, is not yet implemented, but will be for 2.0 final)

API

Requests

Requests, aka injection points, can be defined using the metadata tag [Inject] atop the var, setter or method to inject into. For constructor injection, no metadata is required.

Named injections can be defined using the syntax [Inject(name="injection name")]. In this case, constructors have to have their metadata placed atop the class itself, not the constructor. This is a limitation of the Flex compiler.

Optional injection requests can be defined using the syntax [Inject(optional=true)]

Mappings

The API is expressed as a DSL to make very fine-grained configuration of each mapping easy and readable:

const injector : Injector = new Injector;

//create a basic mapping:
injector.map(Sprite); //will instantiate a new Sprite for each request for Sprite

//map to another class:
injector.map(Sprite).toType(BetterSprite); //will instantiate a new BetterSprite for each request for Sprite

//map as a singleton:
injector.map(EventDispatcher).asSingleton(); //will lazily create an instance and return it for each consecutive request

//map an interface to a singleton:
injector.map(IEventDispatcher).toSingleton(EventDispatcher);

Beta

So, that's it for now as far as documentation is concerned. The implementation, on the other hand, is very stable and shouldn't regress anything that used to work in 1.x, as long as the API changes are dealt with, of course.

More documentation will soon come here, in the github wiki and as asdocs.

swiftsuspenders's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swiftsuspenders's Issues

Add support for injection into non-public namespaces

It would be great to configure swift_suspenders to inject into non-public namespaces. The use-case for this is through Robotlegs with MVCS entities. This doesn't have severe implications, as often I'm programming to interfaces, but it still seems like semantically, the objects are often implementation details.

Implement factory injection

Instead of letting SwiftSuspenders directly handle the creation of injected values, it might sometimes be useful to delegate that to a factory.
sammyt's Dawn framework supports factory injections, which looks like a perfect match for this functionality.

Syntax proposal:

Injector#mapFactoryClass(whenAskedFor : Class, useFactoryClass : Class, named : String = '');

and

Injector#mapFactory(whenAskedFor : Class, useFactoryInstance : Object, named : String = '');

The second option will enabled configuring a specific instance of the factory. It might be more useful to use child injectors for configuring the factory itself.

Map Singleton bug

Hi,
I think I found a bug in a very specific case. The getInstance will create a new instance in a PostConstruct handler, even if it is mapped as singleton.

My problem was in a more complicated scenario of an command that is dispatched from a PostConstruct in ClassA, and this ClassA was injected in the command class for monitoring purpose, throwing an error.

I minimized the code the following 3 classes to show the bug:

import org.swiftsuspenders.Injector; import flash.display.Sprite; public class Main extends Sprite { public static var injector:Injector; public function Main() { injector = new Injector(); injector.mapSingleton(ClassA); injector.mapSingleton(ClassB); injector.getInstance(ClassA); } }
public class ClassA {
    [Inject]
    public var classB:ClassB;
    public function ClassA() {
        trace("Constructor", this);
    }
    [PostConstruct]
    public function initialize():void {
        trace("Initialize", this, ", classB instance:", classB);
        Main.injector.getInstance(ClassA); // should not create a new ClassA (will throw an error)
    }
}

public class ClassB {
    public function ClassB() {
        trace("Constructor", this);
    }
    [PostConstruct]
    public function initialize():void {
        trace("Initialize", this);
    }
}

The error looks like:

Constructor [object ClassA] Constructor [object ClassB] Initialize [object ClassB] Initialize [object ClassA] , classB instance: [object ClassB] Constructor [object ClassA] Initialize [object ClassA] , classB instance: [object ClassB] Constructor [object ClassA] Initialize [object ClassA] , classB instance: [object ClassB] Constructor [object ClassA] Initialize [object ClassA] , classB instance: [object ClassB]

Let me know what you think.

Romu

Child ApplicationDomains break the injector

We created a RobotLegs SWF (with SwiftSuspenders) and it worked fine standalone. However, when loading this into another Robotlegs SWF (also with SwiftSuspenders) in a child ApplicationDomain at runtime, injection failed in the child SWF, throwing the following exception:

Exception fault: ReferenceError: Error #1065: Variable MyClassView is not defined.
at flash.system::ApplicationDomain/getDefinition()
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/initializeInjection()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:58]

So it seems that when a RobotLegs SWF using SwiftSuspenders loads another RobotLegs SWF using SwiftSuspenders in a child ApplicationDomain, injection breaks completely - it seems as though SwiftSuspenders is using the injector/injection settings from the parent domain?

Loading the SWF into the same ApplicationDomain does work, however this does open up other problems for us. We can use this as a workaround for now, but it would be great to find out whether we're doing something wrong, or whether this is an issue with SwiftSuspenders (or indeed RobotLegs). Our investigation has led us to believe this is an issue with SwiftSuspenders.

Is anyone familiar with this problem?

Hope someone can help,

Mani

Implement live injections

Marking an injection point as "live" should cause it to be updated as soon as the mapped value changes.

Injection doesn't work properly with Hero 4.5

For instance:

If I add my userProxy to my LoginMediator with injection this error happens which doesn't make sense...

Error: Injector is missing a rule to handle injection into property "serviceDelegate" of object "[object UserProxy]". Target dependency: "net.voxel.business::ServiceDelegate", named ""
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:43]
at org.swiftsuspenders::Injector/injectInto()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/Injector.as:125]
at org.swiftsuspenders::Injector/instantiate()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/Injector.as:139]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/createResponse()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:40]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:31]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/InjectionConfig.as:43]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/InjectionConfig.as:49]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:36]
at org.swiftsuspenders::Injector/injectInto()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/Injector.as:125]
at org.swiftsuspenders::Injector/instantiate()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/Injector.as:139]
at org.robotlegs.base::MediatorMap/createMediatorUsing()[/Users/dj/Documents/new_fb_projects/VoxCloud/src/org/robotlegs/base/MediatorMap.as:294]
at org.robotlegs.base::MediatorMap/onViewAdded()[/Users/dj/Documents/new_fb_projects/VoxCloud/src/org/robotlegs/base/MediatorMap.as:275]
at flash.display::DisplayObjectContainer/addChildAt()
at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::$addChildAt()[E:\dev\hero_private\frameworks\projects\framework\src\mx\core\UIComponent.as:7278]
at mx.core::UIComponent/addChildAt()[E:\dev\hero_private\frameworks\projects\framework\src\mx\core\UIComponent.as:7184]
at spark.components::Group/addDisplayObjectToDisplayList()[E:\dev\hero_private\frameworks\projects\spark\src\spark\components\Group.as:2037]
at spark.components::Group/http://www.adobe.com/2006/flex/mx/internal::elementAdded()[E:\dev\hero_private\frameworks\projects\spark\src\spark\components\Group.as:1628]
at spark.components::Group/addElementAt()[E:\dev\hero_private\frameworks\projects\spark\src\spark\components\Group.as:1387]
at spark.components::Group/addElement()[E:\dev\hero_private\frameworks\projects\spark\src\spark\components\Group.as:1345]
at spark.components::SkinnableContainer/addElement()[E:\dev\hero_private\frameworks\projects\spark\src\spark\components\SkinnableContainer.as:761]
at spark.components::ViewNavigator/createViewInstance()[E:\dev\hero_private\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1931]
at spark.components::ViewNavigator/commitNavigatorAction()[E:\dev\hero_private\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1849]
at spark.components::ViewNavigator/commitProperties()[E:\dev\hero_private\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1220]
at mx.core::UIComponent/validateProperties()[E:\dev\hero_private\frameworks\projects\framework\src\mx\core\UIComponent.as:8206]
at mx.managers::LayoutManager/validateProperties()[E:\dev\hero_private\frameworks\projects\framework\src\mx\managers\LayoutManager.as:597]
at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\hero_private\frameworks\projects\framework\src\mx\managers\LayoutManager.as:813]
at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\hero_private\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1180]

Why m_injectionPointLists and m_constructorInjectionPoints are not weakref Dictionaries?

Hi Till,

I don't know if this is the right place to post this question but I was curious to know if there is a reason on why m_injectionPointLists and m_constructorInjectionPoints are not weakref Dictionaries.

I've got a Modular Robotlegs application which loads external swf files which are robolges modules. It looks like I cannot unload them properly. I've run the app through the profiler in FDT4 and after doing a unloadAndStop(true), the current instance number for the module doesn't decrease.

So I made m_injectionPointLists and m_constructorInjectionPoints weakref Dictionaries and I now can unload the modules properly. At least I see the instance number going down.
Problem is that I don't know if that change could break something else. I already run your unit test and everything seems ok.

thanks
Simone

Circular Reference issue with Swift Suspenders

(copied from http://github.com/robotlegs/robotlegs-framework/issues/#issue/1)

There is a circular reference bug if you have singletons that inject eachother.

Trivial example (Flex Builder 3 AS3 project) here: http://www.stevensacks.net/xfer/circbug.zip

And the output:

undefined

at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]
at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:47]
at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:134]
at org.swiftsuspenders.injectionresults::InjectSingletonResult/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/injectionresults/InjectSingletonResult.as:59]
at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:58]

Trouble with mapValue values that evaluate to false

If the value i'm trying to map is Boolean = false or String "" the injection appears to fail.
(didn't try Number = zero yet)

I tried changing !injectionPoint checks to injectionPoint == null, but I couldn't fix it and it's 3am : )

Thoughts?

Injecting a previously injected instance

This might be more of a use case than a bug.
I have a bootstrap loader app with it's own context that prepares a service class by injecting all of it's dependencies.
I then load a sub-app with it's own context and wanted to use injector.mapValue(IMyInterface, myInstance) to inject it around the sub application. This fails because the injector tries to inject the dependencies that have already been injected by the bootstrap into the instance supplied. This seems to be working exactly as intended. Which makes sense. I would like a flag to be able to tell the injector that the injections have already been supplied to the instance and to just map the value.

I have gotten around this by just using the instance passed from the boot strap loader in a service locator style approach; No injections, but this changes the way I test it.

Ideas?

Attempting to instantiate() an interface should throw an informative error

I made the mistake of trying to call injector.instantiate(IThing) instead of on Thing.
The error message from Flash Player wasn't obvious at first:

VerifyError: Error #1001: The method asunit.framework::IRunnerFactory() is not implemented.

It would be nice if SwiftSuspenders could detect the interface and throw an informative error.

injector.mapValue -- XML?

For some reason I can't inject XML? The constructor property is returning XMLList?
Am I a moron? All my other datatypes inject just fine...

Optimize injection point caching to work across all injectors

To improve usability of child injectors in areas requiring high performance, injection points should be cached across mediators.
The problem with that is that injection points are sometimes directly linked to specific injectors because they contain InjectionConfigs. This has to be changed.

Also, it's not clear how to implement the global caching without resorting to a static property of the Injector class, which I'm reluctant to do. Not only will that be hard to unit test, it will also cause problems with caching across ApplicationDomain boundaries, which is highly desirable.

instanciate non-mapped classes

I would like to see an flag on the injector to force it to instanciate non-mapped classes to avoid long lists of simple classes mapping. So, we could do:

injector.instanciateNonMappedClasses = true;

insted of:

injector.mapClass(ClassA, ClassA);
injector.mapClass(ClassB, ClassB);
injector.mapClass(ClassC, ClassC);
...

Child Injector Mapping not stored?

I ran into an interesting problem today while trying to create a child injector and I thought it might be an issue with 1.6. I was mapping an injection by value and event though though injector.hasMapping () returned true i was still giving me a mapping not found error.

i found that if i added a getInstance call it fixed it issue. It did not create a new instance, the dependency was mapped already it just was not being made avaliable.

// Does not work.

var childInjector:IInjector = injector.createChild (injector.applicationDomain);

var vo:InfoGraphicsDataModel = new InfoGraphicsDataModel (item,childInjector);

childInjector.mapValue (IInfoGrahicsDataModel, vo);

childInjector.injectInto (vo.rawContent);

// does work

var childInjector:IInjector = injector.createChild (injector.applicationDomain);

var vo:InfoGraphicsDataModel = new InfoGraphicsDataModel (item,childInjector);

childInjector.mapValue (IInfoGrahicsDataModel, vo);
childInjector.getInstance (IInfoGrahicsDataModel);
childInjector.injectInto (vo.rawContent);

getDefinition failing with loaded swf

I've built a website framework (HandBones) that compiles multiple swfs from an application. There is a main swf and page swfs, the pages each mimic a new context, but in actual fact is a view that is being mediated in the background. This all works fine, but with the new version of Robotlegs and SwiftSuspenders the views inside the pages are not mediating.

This stack might look very complex but all that is happening is that the website is navigating to a page called HelloWorld and it's only got one view component called HelloWorldCanvas with mediator HelloWorldCanvasMediator.


Exception fault: ReferenceError: Error #1065: Variable HelloWorldCanvas is not defined.
    at flash.system::ApplicationDomain/getDefinition()
    at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/initializeInjection()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:58]
    at org.swiftsuspenders.injectionpoints::InjectionPoint()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/injectionpoints/InjectionPoint.as:19]
    at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:31]
    at org.swiftsuspenders::Injector/getInjectionPoints()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/Injector.as:271]
    at org.swiftsuspenders::Injector/instantiate()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/Injector.as:130]
    at org.robotlegs.base::MediatorMap/createMediator()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/base/MediatorMap.as:146]
    at org.robotlegs.base::MediatorMap/onViewAdded()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/base/MediatorMap.as:263]
    at flash.display::DisplayObjectContainer/addChild()
    at org.handbones.samples.site.pages.helloworld.controller::HelloWorldStartupCompleteCommand/execute()[D:\Work\HandBones-Samples\src\org\handbones\samples\site\pages\helloworld\controller\HelloWorldStartupCompleteCommand.as:17]
    at org.robotlegs.base::CommandMap/execute()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/base/CommandMap.as:175]
    at org.robotlegs.base::CommandMap/routeEventToCommand()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/base/CommandMap.as:225]
    at Function/()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/base/CommandMap.as:100]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at org.handbones.base::Page/dispatch()[D:\Work\HandBones\src\org\handbones\base\Page.as:115]
    at org.handbones.base::Page/startup()[D:\Work\HandBones\src\org\handbones\base\Page.as:45]
    at org.handbones.samples.site.pages::HelloWorldPage/startup()[D:\Work\HandBones-Samples\src\org\handbones\samples\site\pages\HelloWorldPage.as:20]
    at org.handbones.base::PageMediator/onRegister()[D:\Work\HandBones\src\org\handbones\base\PageMediator.as:23]
    at org.robotlegs.base::MediatorBase/preRegister()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/base/MediatorBase.as:76]
    at org.handbones.base::PageMediator/preRegister()[D:\Work\HandBones\src\org\handbones\base\PageMediator.as:18]
    at org.robotlegs.base::MediatorMap/registerMediator()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/base/MediatorMap.as:163]
    at org.robotlegs.base::MediatorMap/createMediator()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/base/MediatorMap.as:148]
    at org.robotlegs.base::MediatorMap/onViewAdded()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/base/MediatorMap.as:263]
    at flash.display::DisplayObjectContainer/addChildAt()
    at org.handbones.samples.site.view::PageContainer/show()[D:\Work\HandBones-Samples\src\org\handbones\samples\site\view\PageContainer.as:70]
    at org.handbones.samples.site.view::PageContainerMediator/pageChange_handler()[D:\Work\HandBones-Samples\src\org\handbones\samples\site\view\PageContainerMediator.as:43]
    at org.robotlegs.base::EventMap/routeEventToListener()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/base/EventMap.as:181]
    at Function/()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/base/EventMap.as:107]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at org.robotlegs.mvcs::Actor/dispatch()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/mvcs/Actor.as:98]
    at org.handbones.base::Navigator/dispatchNavigatorEvent()[D:\Work\HandBones\src\org\handbones\base\Navigator.as:126]
    at org.handbones.base::Navigator/navigateToPage()[D:\Work\HandBones\src\org\handbones\base\Navigator.as:108]
    at org.handbones.base::Navigator/swfAddress_change_handler()[D:\Work\HandBones\src\org\handbones\base\Navigator.as:155]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at com.asual.address::SWFAddress$/_dispatchEvent()[D:\Work\AS3Library\src\com\asual\address\SWFAddress.as:144]
    at com.asual.address::SWFAddress$/setValue()[D:\Work\AS3Library\src\com\asual\address\SWFAddress.as:398]
    at org.handbones.base::Navigator/setAddress()[D:\Work\HandBones\src\org\handbones\base\Navigator.as:61]
    at org.handbones.base::Navigator/gotoPageId()[D:\Work\HandBones\src\org\handbones\base\Navigator.as:47]
    at org.handbones.controller::ExecuteActionCommand/execute()[D:\Work\HandBones\src\org\handbones\controller\ExecuteActionCommand.as:43]
    at org.robotlegs.base::CommandMap/execute()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/base/CommandMap.as:175]
    at org.robotlegs.base::CommandMap/routeEventToCommand()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/base/CommandMap.as:225]
    at Function/()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/robotlegs-framework/src/org/robotlegs/base/CommandMap.as:100]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at org.handbones.base::ActionMap/dispatch()[D:\Work\HandBones\src\org\handbones\base\ActionMap.as:121]
    at org.handbones.base::ActionMap/executeAction()[D:\Work\HandBones\src\org\handbones\base\ActionMap.as:99]
    at Function/()[D:\Work\HandBones\src\org\handbones\base\ActionMap.as:41]

Like I said, this was working in the previous versions and I can't seem to find the problem.

I've checked that the MediatorMap has the correct mapping.
I've tried to pass the current application domain to loaded swf.
I've checked that all injection are satisfied.

I've have two source bundles one with RL-v1.0.3 and one with RL-v1.1.1. Just let me know, I can send them over.

Any advice would be great, I'm really stuck here.
Thanks!

injector.unInjectTo()

If I inject something to a loaded content(in a child application domain), it will be impossible to unload that content from memory. Because the loaded content itself and it's class definition is saved in there dictionaries inside the Injector instance.
So I suggest an unInjectTo(target:Object) method. It's important to dynamically loading modules.

public function unInjectInto(target : Object) : void
{
if (m_attendedToInjectees[target])
{
delete m_attendedToInjectees[target];
}

        var ctor : Class = getConstructor(target);

        if (m_injectionPointLists[ctor])
        {
            delete m_injectionPointLists[ctor];

            var description : XML = describeType(ctor);
            delete m_injectionPointLists[[email protected]()];
        }

        if(m_constructorInjectionPoints[ctor])
        {
            delete m_constructorInjectionPoints[ctor];
        }
    }

mapSingletonOf slightly broken?

Hi Till,

just upgraded to SwiftSuspenders-1.0RC5 and find mapSingletonOf somehow broken:

This is the code that used to work with an oder version (1 month or so):

// full access interface for use in Commands
injector.mapSingletonOf(IVideoModel, VideosModel);
// readOnly interface for use in mediators (just to retrieve data)
injector.mapSingletonOf(IVideoModel_RO, VideosModel);

Both IVideoModel and IVideoModel_RO referenced the very same instance of VideosModel (same id in Debugger).

Since I've upgraded, thats no more true.. I have now two different instances of VideosModel lying around (different ids).

As a workaround, I've tested the mapVaule approach and it on the other hand still works as expected:

var videosModel:VideosModel = new VideosModel();
injector.mapValue(IVideoModel, videosModel);
injector.mapValue(IVideoModel_RO, videosModel);

So, my project isn't broken, but maybe there is something you could check?

Thanks - and thumbs up for SwiftSuspenders! :-)

Steffen

Add meaningful trace to createDummyInstance error handling

Please add some more trace info in ConstructorInjectionPoint::createDummyInstance.
Currently there is only a trace(error); so when I ran into a null pointer error because of the dummy instance creation flash player bugfix I had to spend a lot time to track down where the error trace was coming from.

Instead of:
catch (error : Error)
{
trace(error);
}

Use something like:

catch (error : Error)
{
trace("Error when creating dummy instance of class " ,clazz, error);
}

Or don't write anything. This could save someone a lot of trouble.

Infinite Loop - Stack Overflow

Hi,

I just upgraded to 1.5.0 and am using RL 1.0.0b6. When I try to instantiate my application, I get the following stack overflow. By tracing through the code it looks like he keeps looking for his parent event though there should be only one parent. Did I configure something wrong or is this a bug? Thanks!

Jim

Error: Error #1023: Stack overflow occurred.
at org.swiftsuspenders::Injector/getAncestorMapping()[C:\usr\flex\SwiftSuspenders\src\org\swiftsuspenders\Injector.as:221]
at org.swiftsuspenders::InjectionConfig/getResponse()[C:\usr\flex\SwiftSuspenders\src\org\swiftsuspenders\InjectionConfig.as:44]
at org.swiftsuspenders::InjectionConfig/getResponse()[C:\usr\flex\SwiftSuspenders\src\org\swiftsuspenders\InjectionConfig.as:47]
at org.swiftsuspenders::InjectionConfig/getResponse()[C:\usr\flex\SwiftSuspenders\src\org\swiftsuspenders\InjectionConfig.as:47]
at org.swiftsuspenders::InjectionConfig/getResponse()[C:\usr\flex\SwiftSuspenders\src\org\swiftsuspenders\InjectionConfig.as:47]
at org.swiftsuspenders::InjectionConfig/getResponse()[C:\usr\flex\SwiftSuspenders\src\org\swiftsuspenders\InjectionConfig.as:47]
at org.swiftsuspenders::InjectionConfig/getResponse()[C:\usr\flex\SwiftSuspenders\src\org\swiftsuspenders\InjectionConfig.as:47]
at org.swiftsuspenders::InjectionConfig/getResponse()[C:\usr\flex\SwiftSuspenders\src\org\swiftsuspenders\InjectionConfig.as:47]

Creation of classes and their injection in Child Injectors

been playing with child injectors... at the moment if a mapping is not overridden in the child injector the parent injector creates AND injects the instance. This means that any injections within the requested class are those mapped in the parent, even if those rules are overridden in the requesting child.

It would be cool if you could choose which injector actually injects the class. Obviously this brings up a whole load of issues (ie those mapped as Singletons should always be as is.

Error When Injecting a RemoteObject

I am trying to configure my services and inject some remote objects on demand. This error is getting returned:

TypeError: Error #1034: Type Coercion failed: cannot convert mx.rpc.remoting::Operation@2bb0e0e9 to Class.
    at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:94]
    at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:59]
    at org.swiftsuspenders::VariableInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/VariableInjectionPoint.as:58]
    at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:98]
    at org.swiftsuspenders::InjectionConfig/getResponse()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/InjectionConfig.as:73]
    at org.swiftsuspenders::VariableInjectionPoint/applyInjection()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/VariableInjectionPoint.as:58]
    at org.swiftsuspenders::Injector/injectInto()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:98]
    at org.swiftsuspenders::Injector/instantiate()[/Users/shaun/Documents/Development/Workspaces/GanymedeFB4/SwiftSuspenders/src/org/swiftsuspenders/Injector.as:112]
    at org.robotlegs.base::MediatorMap/createMediator()[/Users/joel/Code/robotlegs-framework/src/org/robotlegs/base/MediatorMap.as:129]
    at com.woven.turnersports.admin::AdminContext/startup()[/Users/joel/Code/woven-work/TurnerSportsCapabilitiesAdmin/src/com/woven/turnersports/admin/AdminContext.as:29]
    at org.robotlegs.base::ContextBase/onAddedToStage()[/Users/joel/Code/robotlegs-framework/src/org/robotlegs/base/ContextBase.as:134]
    at flash.display::DisplayObjectContainer/addChildAt()
    at mx.managers::SystemManager/preloader_preloaderDoneHandler()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\managers\SystemManager.as:3019]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.preloaders::Preloader/displayClassCompleteHandler()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\preloaders\Preloader.as:434]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.preloaders::DownloadProgressBar/timerHandler()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\preloaders\DownloadProgressBar.as:1451]
    at mx.preloaders::DownloadProgressBar/initCompleteHandler()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\preloaders\DownloadProgressBar.as:1503]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.preloaders::Preloader/dispatchAppEndEvent()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\preloaders\Preloader.as:291]
    at mx.preloaders::Preloader/appCreationCompleteHandler()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\preloaders\Preloader.as:442]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\core\UIComponent.as:9308]
    at mx.core::UIComponent/set initialized()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\core\UIComponent.as:1169]
    at mx.managers::LayoutManager/doPhasedInstantiation()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\managers\LayoutManager.as:718]
    at Function/http://adobe.com/AS3/2006/builtin::apply()
    at mx.core::UIComponent/callLaterDispatcher2()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\core\UIComponent.as:8633]
    at mx.core::UIComponent/callLaterDispatcher()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\core\UIComponent.as:8573]

The second parameter type of SwiftSuspendersInjector::mapClass

I saw this code at README.textile
var currentTime : Date = new Date();
injector.mapClass(Date, currentTime, 'currentTime');

Isn't the second parameter request Class type? Why there full with a instance? Doesn't the compiler throw a Compile-Time error?

Issue with constructor injection using config xml

The following simple example yields, "Error: Injector is missing a rule to handle injection into target [class Class1]. Target dependency: Object, method: null, parameter: 1". Works fine with the metadata approach.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
    <mx:Script>
        <![CDATA[
            import org.swiftsuspenders.Injector;

            public function init():void
            {

                var diconfig:XML =
                <types>
                    <type name='Class1'>
                        <constructor>
                            <arg injectionname="exampleObjectParam" />
                        </constructor>
                    </type>
                </types>

                var injector:Injector = new Injector(diconfig);
                injector.mapValue(Object,{mode:'test'},'exampleObjectParam');
                var o:Class1 = injector.instantiate(Class1);
                trace(o.param1);
            }
        ]]>
    </mx:Script>
</mx:Application>

package
{
    import flash.events.IEventDispatcher;


    public class Class1 extends Object
    {
        public var param1:Object;

        public function Class1(p:Object)
        {
            param1 = p;
        }

    }
}

PropertyInjection fails poorly

In a class some place i have:

[Inject(name="IncompleteIntervalsService")]
public var intervalService:IIntervalService;

But I don't have a mapping declared (because of a typographic error, yay magic strings in meta)

injector.mapSingletonOf(IIntervalService, IncompleteIntervalService, "IncompleteIntervalService");

(missing an 's')

Causes an unhandled RTE. I think it should raise an exception in PropertyInjectionPoint.as line 37 (where mappings is null)

Suggestions for hooks in 2.0

Hey Till,

As you know i've been writing an map/injection hook system for 'Boiler' which just extends Injector. A couple of things I cam across you may find useful:

  • There are two types of before/after scenarios: (a) injection and (b) mapping. I find that further distinction when 'adding' handlers is pointless. Eg: injector.addMappingHandler(HandlerClassOrInstance), and several interfaces - IBeforMapHandler IAfterMapHandler etc.. You can see what i mean here: https://github.com/squeedee/Boiler/blob/master/HookableSuspenders/src/main/hookableSuspenders/MappingHandlerCollection.as#L26
  • Hooking into 'before injection' and 'after injection' isn't easy, because I normally want to get my own injections in the handlers (I've seen a lot of stack dumps lately)
  • A more useful form of before/after injection handler would be one applied to a specific mapping... eg getMappping(BlahClass).addInjectionHandler(this). This would often be called from afterMappingHandlers.

Perhaps you know all this, and probably you'll disagree, but I thought I'd cast some opinions. Happy to chat on Skype if you need me to make more sense than i did here :D

Nonrequired injections proposal

When the injection is missing sometimes is preferable to receive a null value than an Exception.
For this cases I would like to have an option like this:

[Inject (optional=true)] public var someService:SomeService;

Restrict access to mappings for child injectors

Is there a way to restrict access to some mappings for child injectors?

so to have some private mappings in the parent injectors which are not accessible by its children?

This came up because right now we are facing that situation.

We have some singletons which should stay private in the context of the main application but some other which should be available for the children.

Could it be a good idea to add this functionality?

Method Injection for multiple optional parameters do not work..

Here's an example of what I'm taking about. A method provides completely optional parameters for all arguments, but the injector doesn't seem to consider ALL possible injections once the first (or subsequent) parameter gracefully fails.

For example, I mapped the last named parameter "gxml.attribute" to a valid value, but SwiftSuspenders seems to ignore it because the first dependency ("gxml.display") isn't fuffilled. Shouldn't it consider all dependencies in the method for injection, even though the first optional parameter gracefully failed?

bc. [Inject(name='gxml.display', name='gxml.behaviour', name='gxml.text', name='gxml.attribute')]
public function setCustomPropAppliers(dispPropApplier:IPropertyApplier=null,behPropApplier:IPropertyApplier=null,textPropApplier:IPropertyApplier=null,attributePropApplier:IPropertyApplier=null):void {
if (dispPropApplier) this.dispPropApplier = dispPropApplier;
if (behPropApplier) this.behPropApplier = behPropApplier;
if (textPropApplier) this.textPropApplier = textPropApplier;
if (attributePropApplier) this.attribPropApplier = attributePropApplier;
}

The only way i can get attributePropApplier (4th parameter) to work is to set it to the first parameter of the method. Is there a way to consider ALL possible injection points in a method? I'm rather lazy to create 4 seperate setter methods just to support this, and the use of a single method seems more meaningful to the end user.

External Injection Point Configuration - XML or new syntax

With the discovery that annotations/metadata can indeed be used in Flash Professional (by selecting "Export SWC" under publish settings) the XML configuration of injection points seems less useful.

On the other hand being able to configure injection points externally could be useful for integration with external libraries or cases where modifying classes (to add metadata) is impossible/undesirable.

As far as I can tell though, currently the XML needs to be provided when constructing the container - which might not be very convenient. It might be worth expanding the API to allow for external configuration of injection points at runtime. Thoughts?

Confused about singleton in parent injector

Hi,

I hope this is the correct place to ask the question. I want to define a singleton object with my shell parent injector mapping (e.g. SessionModel), and then inject the SAME singleton instance into my modules which are children injectors of the shell injector. The injection mapping is indeed happening in the children but it is not the same instance as the parent like I had expected. Is this just a misunderstanding of how parent/child injectors work or perhaps a bug? Thanks!

Jim

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.