For simplicity lets say I have class A and that has an injection point of
interface IFoo. I want to inject into this an implementation of IFoo called
Foo. Class Foo's only constructor takes an instance of class C.
Class C is abstract, there are no public implementations of it. The only
way to get an instance of class C is to invoke a method on an instance of A
(i.e. myA.getC()).
If you want real world names for these, this is on Android using Roboguice
and A is an Activity or Fragment and C is LoaderManager which is abstract
and the can only be retrieved by calling getLoaderManager() on the Activity
of Fragment to get the LoaderManager specificly for that Activity or
Fragment..
And note that there is not just a single instance of A, There will be
instances of A created and destroyed as the user uses the app.
I considered getting rid of the constructor parameter in Foo and adding a
setC method that A has to explicitly invoke itself, but that requires
exposing setC in IFoo interface which makes no sense as C is an
implementation detail of Foo and has no business being exposed in the
interface IFoo. The point of DI is that I should not have to include the
implementation details of how to initialize class Foo and only depends on
IFoo.
I have done the custom injection thing for injecting the target class name
for logger, but in this case I need the actual instance being injected into
to to use in the provider. I can probably do it with CustomInjection but it
sure seems the wrong way to go, but probably what I will be forced into. To
me the whole custom injection thing seems like I am rewriting much of the
logic
I have gathered from the web that the designers of Guice have a
philosophical bias that considers a binding knowing anything about the
target to be horrible design and would actually design the it to make this
hard if not impossible. But I'm not sure I see a good way around this.
I have a concept of how this and other related things could be designed
easily into the external API, but I'm not sure if they would go for this.
The idea is to have another provider interface that would provide the
context when getting an instance.
public interface ContextualProvider<T, Context>
{
T get(InjectionPoint point, Context target);
}
Which would let me implement this as:
bind(IFoo.class).inTarget(Matchers.subclassesOf(A.class)).toProvider(new
ContextualProvider<IFoo, A>()
{
IFoo get(InjectionPoint point, A a)
{
return new Foo(a.getC());
}
}
Might have to be reworked slightly for type safety, but hopefully you get
the idea.
Something like this would also simplify the logger example shown for custom
injection which is way too much work just to get the name of the target
class.
Are there any other thoughts on how to get around this?
This idea of getting access to the InjectionPoint would also let you easily
query for other annotations being applied to the Injection and getting
their values to alter the object that is provided.
--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.