users@hk2.java.net

Re: Dynamically bind a Factory to a ServiceLocator?

From: john wells <john.wells_at_oracle.com>
Date: Wed, 29 Oct 2014 15:30:30 -0400

On 10/28/2014 9:10 PM, buko wrote:
> Thanks for the quick reply!
>
> > You are correct, this is more difficult than it should be.
>
> It's just awesome that is possible.
Thanks
>
> > Create your own implementation of FactoryDescriptors to add the
> previous two descriptors into
>
> To be clear, FactoryDescriptors has two methods that returns the
> asFactory and asService descriptors. In this case, the descriptor
> returned from (1) is the asFactory descriptor and the descriptor
> returned from (2) is the asService descriptor?
Yeah, the names are unfortunately not very clear. But I think you got
it correct
>
> >and I think there are at least two things this shows a need for:
>
> I'm all for the low-level utilities that make stuff easier. One of the
> great things about hk2 is that it is fully dynamic and it's possible
> to enrich the injection world after the ServiceLocator has been
> created and it provides the utilities to do such dynamic/runtime
> injection.
>
> On a higher level, what I really want to do is type-driven custom
> injection.
>
> In the current model users want to be able to inject T. But the
> framework needs to create T. So I ask users to register a TDescriptor
> and then use the RunLevel mechanism to introduce a run-level where
> (before any user code is invoked) I will go through the
> ServiceLocator, find each TDescriptor, and then create and bind
> Factory for each TDescriptor so that @Inject T will work.
This sounds more like JustInTime binding. You might be able to do this
better with this: JustInTimeInjectionResolver
<https://hk2.java.net/2.4.0-b06/apidocs/org/glassfish/hk2/api/JustInTimeInjectionResolver.html>.
the JIT resolver allows you a second chance to add in a service (or set
of services) when an Injection point lookup fails.
>
> But what would be really cool is if I could bind an injection resolver
> to the type T. (The limitation of the annotation-driven custom
> injection is that it doesn't play well when the user simply does
> ServiceLocator.getService(T).) That way any time somebody needs a type
> T my InjectionResolver could look for the TDescriptor and create a new
> T. So adding dynamically adding factories and type-driven custom
> injection boil down to the same thing: the user needs a type T and I
> want to step in and provide custom logic to create that T based on
> information available in the ServiceLocator. But perhaps type-driven
> custom injection might be simpler...
Tell me if the JustInTimeInjectionResolver does the trick. In any case
I want to add those utilities to hk2 to make using and adding factories
easier. In fact, I've already made the change that puts
FactoryDescriptorsImpl into a public package.
>
> On Tue, Oct 28, 2014 at 8:57 PM, john wells <john.wells_at_oracle.com
> <mailto:john.wells_at_oracle.com>> wrote:
>
> You are correct, this is more difficult than it should be. You
> can do it, but you'll have to become an expert on how to construct
> descriptors. I also think it is worth adding a helper function to
> ServiceLocatorUtilities, like "addFactoryConstant" or something
> like that.
>
> In the meantime, the best thing is probably to:
>
> 1. Use
> BuilderHelper.activeLink(WhatTheFactoryIsProviding.class).buildProvideMethod()
> to get the ActiveDescriptor for the provide method of the factory
> 2. Use BuilderHelper.createConstantDescriptor to get the
> ActiveDescriptor for the factory
> 3. Create your own implementation of FactoryDescriptors to add
> the previous two descriptors into
> 4. Use ServiceLocatorUtilities.addFactoryDescriptors to add your
> factory
>
> This is kind of roundabout, and I think there are at least two
> things this shows a need for:
>
> 1. A utility implementation of FactoryDescriptors so that you
> don't have to create one yourself
> 2. Methods in BuilderHelper and ServiceLocatorUtilities that
> allow you to add constant factories
>
> So... it is possible today, just tricky, and it shouldn't be so
> tricky IMO...
>
>
> On 10/28/2014 8:15 PM, buko wrote:
>
> For various reasons I'd like to be able to dynamically add a
> Factory to a ServiceLocator after the ServiceLocator has been
> created. Try as I might can't figure out how this is done.
>
> Let's say I have an instance of GenericFactory<T> and a type
> T. Given a ServiceLocator I'd like to add the factory instance
> such that other users (before I proceed to the next runlevel)
> can @Inject T and it'll call the factory instance.
>
> I've been poking at this for a while using
> BuildHelper.createConstantDescriptor and the
> FactoryDescriptors interface but nothing works. Any insights
> on how this might look?
>
>
>