First of all,
thank you very much for your detailed
answers.
> No worries, I'm working on updating the FAQ at the moment so this
is
> actually very timely :)
Good to know, I have a few more questions
:-)
> The example extender bundle uses
Sisu to scan bundles for components
> as they are started:
>
> https://github.com/eclipse/sisu.inject/blob/master/org.eclipse.
> sisu.inject.
> extender/src/org/eclipse/sisu/launch/internal/SisuActivator.java#L113
I had a look at the source code and
made some simple tests with a chain of two bundles, and everything worked
like magic :-)
If I understood correctly, the extender
instantiates multiple Provider<Injector> objects that will be all
registered into the DefaultBeanLocator.
Correct - at the moment it filters on the internal BundleInjector type name when querying the service registry to avoid accidentally picking up unrelated injectors but there's no reason why it couldn't be adapted to pull in injectors registered outside of Sisu. It also casts the resulting service instances to Provider<Injector> rather than the internal BundleInjector type to support refresh of the extender bundle (so you could conceivably update the extender if necessary without disturbing running application bundles). If it attempted to cast them to the current BundleInjector type and the extender bundle had been refreshed then they would not be compatible, but since the Provider and Injector types are imported from outside then they should still be compatible.
The additional registration in
the OSGi service using the extended bundle bundlecontext is only used to
perform proper removal from the DefaultBeanLocator when the owning bundle
goes offline.
Yes - the alternative would be to also handle this using the bundle tracker, but then you'd still need somewhere to keep the reference to the injector and the service registry seems the best place to keep this.
Not related to Sisu, but I noticed that
the SisuActivator uses a WeakReference to the DefaultBeanLocator. Is that
used for supporting a bundle update/refresh ?
Correct - the idea is that if the extender bundle is refreshed and there is an active locator (ie. at least one previous application bundle is still running) then it will re-use that rather than creating a new locator and potentially splitting the application.
> * extend dynamic updates to apply to injected
instances, not
> just injected collections (https://bugs.eclipse.org/bugs/show_bug.
> cgi?id=386430)
The above bugzilla entry states that
injected lists and maps are already supported. Does it refer to Guice MultiBindings
(http://code.google.com/p/google-guice/wiki/Multibindings) or what ?
This is unrelated to multi-bindings - the bean locator returns an iterable sequence of bean entries which can be wrapped into lists, maps, etc. This wrapping is done by the WireModule when it detects that you are injecting a collection. It automatically binds a provider that queries the locator and wraps the result in the appropriate type. The injected collection is backed by the dynamic iterable returned from the locator, meaning that its content will change as injectors are added/removed from the locator. It uses a special ranked sequence under the covers which means we can update the sequence even while you're iterating over it, and also avoid querying potentially expensive sources of bindings (like the Eclipse/OSGi registries) until they are required.
Also, when classes are found via scanning,
what happens when multiple implementations of the same interface exist?
Does Sisu automatically create a Guice multibinding ?
No, scanned implementations are typically bound using a special wildcard key which means we avoid binding clashes while still allowing the locator to find them when querying on the interfaces. This avoids a combinatorial explosion of bindings and also solves the issue of which interfaces/supertypes to bind against. It also lets the locator query using generic type signatures (even involving bounded type parameters). You can however use the CDI @Typed annotation to force Sisu to bind an implementation to a given list of types.
Does Sisu support Guice's chained linked
bindings (http://code.google.com/p/google-guice/wiki/LinkedBindings)?
Sisu is designed to support any kind of binding
I am asking because my application comes
with default implementation of certain interfaces and base classes, but
we need a simple way of letting developers override them with custom implementations.
Ideally such overrides would be implemented in an extra OSGi bundle to
be included in the final application distribution. Would a simple Guice
module implemented in the extra bundle and declared in META-INF/services/com.google.inject.Module
work?
M5 of Sisu will automatically install modules declared in META-INF/services/com.google.inject.Module. Since this is an extra bundle then it is technically a new injector with the overridden bindings (unless you attached it as a fragment to the bundle with the original implementations). To override the original bindings it needs to use a higher ranking (just like a service needs a higher ranking to appear before others) by using the following binding:
I'm also looking at adding something like a @Rank annotation to let you declare different implementation rankings without having to mess around with the low-level RankingFunction type.
And now my last question, at least for
today :-). My application is using the OSGi extender pattern for collecting
metadata about classes included in its bundles. If I wanted our extender
to create a guice module on-the-fly to bind those classes, I believe I
could mimic the behaviour of the BundleInjector class that is included
in the Sisu extender. Is that right?
Yes, just use the SpaceModule and WireModule as necessary and register the injector to the locator. Note if you define a binding to the locator instance in your injector then it will be automatically registered by virtue of Guice's automatic instance injection (see the autoPublish method in the locator). Otherwise you'd need to register it manually using the "add(injector, rank)" method.
I would need to refactor the Sisu
extender to make some code more reusable, and then have my extender create
additional BundleInjectors when appropriate. Would it be an issue for Sisu
if more than one BundleInjector exist for the same bundle?
Thanks in advance.
GianMaria Romanato._______________________________________________
sisu-users mailing list
sisu-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/sisu-users