getOrCreateInjectorFor, and singleInjectorMode

3 views
Skip to first unread message

dtyrell

unread,
Mar 14, 2009, 9:18:23 AM3/14/09
to Smartypants IOC
Hello,

I have two little questions that I've been meaning to ask.

To create the Injector for my application I've been using the static
method: SmartyPants.getOrCreateInjectorFor(). It takes an instance as
a parameter.

I'm not entirely sure what that parameter is for, but I assume it
doesn't really matter if I only want one Injector for my application -
I inject that Injector into any objects that need it after startup. No
one else in the my should call SmartyPants.getOrCreateInjectorFor().

SmartyPants.singleInjectorMode: I assume that allows one to use
SmartyPants as a Singleton. Is that the general idea there?

Basically, I want to avoid using SmartyPants as a Singleton. To do
that I assume I must set singleInjectorMode to false, create a single
Injector, and inject that into anyone who needs access to it. Does
that sound about right?

I realise that singleInjectorMode might be useful, but it seems a
little dangerous - once turned on it can't be turned off,
understandably. This might lead to a situation where third-party, or
externally loaded, sub modules/applications that make use of
SmartyPants and singleInjectorMode interfere with the application that
they get loaded into. Just a thought. Perhaps I'm missing the point!

Many thanks,

Josh McDonald

unread,
Mar 14, 2009, 10:25:28 PM3/14/09
to smartyp...@googlegroups.com
G'day,

SmartyPants.getOrCreateInjectorFor(instance) is both a convenience method, and the "bootstrap point" for apps that rely on SP.

In multiple-injector mode, it first checks to see if there's already an injector "associated with" the instance in question, and will return if an injector is found. If the instance is a DisplayObject, SmartyPants will traverse back up the display list looking for an existing object with a matching injector, and if so returns.

Finally, it checks to see if there's an injector for Application.application, but that's getting removed for 1.0, as with the inclusion of single-injector mode it's unnecessary.

The reason for these shannegans is of course the fact that we need to be able to inject into already-created objects without a fuss, otherwise we lose the benefits of MXML - in reality nobody would ever want to use the Injector :)

You can jump from single-injector mode to multiple-injector mode any time you like, but you can't switch *back* to single-injector mode again if multiple injectors have been created. Note that this isn't a technical limitation, just one I'm enforcing because to me it seems better to disallow the possibility than the headaches you would get trying to debug your application should you try it and things not work. If that seems like a stupid assumption to you, let me know. We can work together to address the issues - such as deciding which injector to promote to "single" state, how to merge the rulesets, etc. As you can see, it's a complicated operation :D

SmartyPants powers a whole bunch of applications, but as far as I know none that are multi-module, so there's nothing in there specifically tailored to suit this type of architecture. However I think it *is* an important thing to consider, so I'll definitely work with you to get it sorted if it's not currently meeting your needs. An interesting idea would be changing the "per-vm" level of the configuration to "per-module". I'll also be adding the ability to nest rulesets in order to address the "robot-legs" problem, and this could be leveraged to support module-specific rules while also maintaining global application-wide rules.

If you're compiling a module against the SmartyPants SWC but *not* actually referencing any of the classes, I don't know whether or not the compiler will remember to retain the annotations. It probably will, but I can't be 100% sure :) But if you compile your modules without the SWC file, you'll have to add a bunch of "--keep-as3-metadata" options to your compiler settings.

I hope that clears things up somewhat, if not (which is quite possible) just let me know!

Cheers,
-Josh


2009/3/14 dtyrell <Dar...@gmail.com>



--
"Therefore, send not to know For whom the bell tolls. It tolls for thee."

Josh 'G-Funk' McDonald
  -  jo...@joshmcdonald.info
  -  http://twitter.com/sophistifunk
  -  http://flex.joshmcdonald.info/

dtyrell

unread,
Mar 15, 2009, 8:48:39 AM3/15/09
to Smartypants IOC
Hi Josh,

Ah, I think that way that I'm using SmartyPants is probably quite
different from how it's typically used in Flex applications. This
would be because I like to keep my view components self-contained and
stand-alone: they don't reference anything outside of themselves,
keeping them re-usable across applications and contexts.

I manage this approach by using the Mediator pattern. A Mediator has a
reference to it's view component and not the other way around - again,
to prevent the view component from being coupled to the application.
Mediators are created for view components automatically.

My Mediators have their dependencies injected into them by a single
Injector when they are created by the framework. This means that I
never inject into any MXML components - something that I believe is
fairly expensive in any case (calling describeType on a UIComponent
would be pretty slow I imagine) - and I don't have any Classes that
"request" injection. My Commands and Mediators use annotations to
declare their dependencies, but my framework is responsible for doing
the Injection with its single Injector instance.

The fact that I've got a little framework to take care of creating my
application actors seems to simplify matters from an injection point
of view: after creating an actor I inject into it, so none of my
Classes need to explicitly request injection themselves. This means
that SmartyPants doesn't ever have to figure out context or anything
like that - which is only necessary when you have MXML components that
require dependency injection.

Seems I got the singleInjector mode switching thing backwards, so it's
not as dangerous as I thought.

Rock on,
shaun
> 2009/3/14 dtyrell <Dars...@gmail.com>
>   -  j...@joshmcdonald.info

Josh McDonald

unread,
Mar 15, 2009, 9:18:50 AM3/15/09
to smartyp...@googlegroups.com
I've done something similar in a recent project, it's a pretty nice approach. Although mine's better described as a presentaion-model than a mediator.

At the moment, you're right about describetype being slow against a UIComponent- but that's because I've had to re-implement DescribeTypeCache due to a bug in the Flex SDK implementation. I've submitted a fix to Adobe, but I don't think it made it into 3.3. It should be in 4, and in should Adobe release another version of 3, it'll probably be included. However you could monkey-patch a fixed implementation and remove the one from Reflection.as, and then you'd get the speedup of the cache because DescribeType is part of the binding system - any MXML-based class with bindings will already be in the DescribeTypeCache.

Cheers,

-Josh

2009/3/15 dtyrell <Dar...@gmail.com>
  -  jo...@joshmcdonald.info
Reply all
Reply to author
Forward
0 new messages