[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [sisu-users] The importance of @Named in sisu
|
That is all perfectly clear. I'm gestating more doc contributions based on this.
On Sun, Feb 2, 2014 at 1:46 PM, Stuart McCulloch <mcculls@xxxxxxxxx> wrote:
> 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
>
> _______________________________________________
> sisu-users mailing list
> sisu-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/sisu-users