A couple of angles:
(1)
Do you actually care about what T is? I gather the code you posted is only
a snippet, but it's worth thinking about whether you can simply code
to an Updatable
and not a "T extends Updatable."
(2)
I'm guessing you're binding the a discrete set of Updaters as TypeLiterals
somewhere to distinguish one from another. Alternatively, you could use a
MapBinder, to bind Map<UpdaterType, Updater>. Then you could:
scheduler. addRecurringTask(
new InjectableRunnable<Updater<SomeUpdatable>>(
injector, updaterType);
);
and in your Runnable, you could use the injector to get the Map<UpdaterType,
Updater> to get the appropriate instance.
(3)
If you have the injector at the point of InjectableRunner creation, you
could use the injector to create that runnable (via a MapBinder like the
above), or at the least use the injector to inject its members so you can
limit the places in code that need to know about an injector. Essentially
I'm saying that you should be able to get rid fo the "InjectableRunnable"
because you can create the actual runnables themselves and then using the
injector to inject members at the point of creation.
(4)
Top-level, sometimes it's convenient to model the property that
distinguishes differently parameterized types of a generic type from the
type literal domain to a "map key" domain, or something similar. That is,
at some point in your code, if you're creating these objects dynamically
(i.e., not through a static object relationship graph), you need to know
which incarnation of a generic type you need. That bit of information most
likely exists as _something_ other than an actual type in the creation
code. For example, if you need Foo<Apple>, then something in your code
probably indicates that you need Foo<Apple> and not Foo<Banana>. Perhaps a
URL param does this. You can then take that bit of information and use it
to lookup the class in a map.
-Fred
On Sat, Sep 11, 2010 at 11:25 AM, Brian Pontarelli <[email protected]>wrote:
> I'm attempting to create a reusable class that can be used to update many
> different types. The updater looks like this:
>
> public class Updater<T extends Updatable> implements Runnable {
> private final Updatable target;
>
> @Inject
> public Updater(T target) {
> this.target = target;
> }
>
> public void run() {
> target.update();
> }
> }
>
> These Updaters are called via a scheduler. The scheduler takes Runnables
> but knows nothing of Guice. Therefore, I create a class called
> InjectableRunnable that has the Injector and a Key. It looks like this:
>
> public class InjectableRunnable<T extends Runnable> implements Runnable {
> private final Injector injector;
> private final Key<T> key;
>
> public InjectableRunnable(Injector injector, Key<T> key) {
> this.injector = injector;
> this.key = key;
> }
>
> public void run() {
> Runnable instance = injector.getInstance(key);
> instance.run();
> }
> }
>
> Then I add this to the scheduler like so:
>
> scheduler. addRecurringTask(
> new InjectableRunnable<Updater<SomeUpdatable>>(injector, new
> Key<Updater<SomeUpdatable>>() {})
> );
>
> However, the runtime types aren't available and I'm getting the usual
> expcetion:
>
> Caused by: java.lang.AssertionError: Unexpected type. Expected:
> java.lang.reflect.ParameterizedType, got:
> sun.reflect.generics.reflectiveObjects.TypeVariableImpl, for type literal:
> T.
>
> I can't seem to figure out how to get the generics to take. There are a
> couple ways I can refactor to remove the generics and get it working, but I
> really wanted to see if I could get the generics going. Anyone have the fix?
>
> Thanks,
> -bp
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "google-guice" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected]<google-guice%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/google-guice?hl=en.
>
>
--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-guice?hl=en.