[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [sisu-users] The importance of @Named in sisu
|
On 1 Feb 2014, at 22:18, Benson Margulies <benson@xxxxxxxxxxxxx> wrote:
> So, I have an @Named class (call it Fred) with an @Inject constructor
> that called for a Map<String, T> to pick up all the @Named classes of
> class T.
>
> Now, this is The Very Class that I obtain from the injector in
> bootstrap. I create the injector, and then call
> createInstance(Fred.class).
>
> In the process of cleaning something else up, I removed the @Named.
>
> The injection of the Map then failed in Guice -- before Sisu ever got
> run to do anything. When I put the @Named back on the class, all was
> well.
>
> I'd be grateful for some insight into the principle.
Hi Benson,
First some background: in plain Guice (without Sisu) you need to explicitly bind everything you’re going to @Inject before you create the injector, unless it’s covered by the built-in or just-in-time bindings:
https://code.google.com/p/google-guice/wiki/BuiltInBindings
https://code.google.com/p/google-guice/wiki/JustInTimeBindings
Once the injector is created the bindings are effectively locked in place - there’s no easy way to dynamically add bindings to an injector later on (see https://code.google.com/p/google-guice/issues/detail?id=49).
Sisu aims to simplify this process and also provide a form of auto-binding with the WireModule [1] without needing any internal changes to Guice. It uses the Guice introspection SPI to analyse all bindings in the modules given to the WireModule - duplicate bindings are eliminated/merged as appropriate and any missing bindings, such as for a dynamic Map<String, T> are bound indirectly to the BeanLocator [2] which acts like a service-locator, populating the results dynamically as required:
https://github.com/eclipse/sisu.inject/blob/master/org.eclipse.sisu.inject/src/org/eclipse/sisu/wire/LocatorWiring.java#L79
One limitation of this ahead-of-time wiring approach is that it can only analyse what it’s given - using your example, if Fred.class is not bound in the modules passed into WireModule then it can’t tell that Fred needs Map<String, T> and doesn’t know to add a binding for it. Because Fred is a concrete class, you can still ask the injector for an instance of it even though there is no explicit binding for it (as concrete classes are one of the just-in-time bindings) but this request will fail later on when the injector attempts to inject the constructor as there is no binding for Map<String, T>.
So how does this relate to the missing @Named? Well the other main module provided by Sisu is the SpaceModule [3], which provides classpath scanning (can be full / indexed / custom) - when the SpaceModule scans its given classpath any class annotated with a JSR330 @Qualifier like @Named will be automatically bound as a component. By removing the @Named annotation, the Fred class is no longer automatically bound by the SpaceModule and therefore won’t be processed by the WireModule.
You can find more examples in the javadoc package descriptions:
1. http://eclipse.org/sisu/docs/api/org.eclipse.sisu.inject/reference/org/eclipse/sisu/wire/package-summary.html
2. http://eclipse.org/sisu/docs/api/org.eclipse.sisu.inject/reference/org/eclipse/sisu/inject/package-summary.html
3. http://eclipse.org/sisu/docs/api/org.eclipse.sisu.inject/reference/org/eclipse/sisu/space/package-summary.html
—
Cheers, Stuart
> _______________________________________________
> sisu-users mailing list
> sisu-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/sisu-users