Gin module binding using annotatedWith and AsyncProvider

548 views
Skip to first unread message

Steve C

unread,
Aug 26, 2012, 1:28:39 PM8/26/12
to google-we...@googlegroups.com
If I want to inject an instance of a specific class based on an annotation, I can do this in a Gin module:

bind(DiSecondary.class).annotatedWith(Special.class).to(DiSecondarySpecialImpl.class);

I also already have:

bind(DiSecondary.class).to(DiSecondaryImpl.class);

I can then retrieve the special instance into my DiMain (Composite wrapping a Panel) constructor with:

@Inject
public DiMain(@Special DiSecondary special) {
  add(special);
}

But, if I want to code-split DiSecondarySpecialImpl using AsyncProvider, the analogous approach does not work:

@Inject
public DiMainAsync(@Special final AsyncProvider<DiSecondary> diSecondaryProvider) {
  diSecondaryProvider.get(new AsyncCallback<DiSecondary>() {
    public void onFailure(Throwable caught) {}
    public void onSuccess(DiSecondary result) {   
      add(result);
    }
  });
}

I get a GWT compiler error.  If I remove the annotation, then, of course, I get the non-special implementation.

Am I being unreasonable to expect that the compiler could apply the annotation to the async provider for the base class instead of the base class itself?

Is there a different route that I can use to get the desired behavior (annotation-based selection of an alternate async loaded class)?


Thomas Broyer

unread,
Aug 26, 2012, 1:43:09 PM8/26/12
to google-we...@googlegroups.com
You should ask on https://groups.google.com/d/forum/google-gin as the GWT Compiler is not involved in these decisions, only the GIN generator.

BTW, what's the error? Does it work if you don't use an AsyncProvider? (direct injection, or through a Provider)

And as a workaround / alternative, I suppose you could use a "@Special Provider<DiSecondary>" and an explicit GWT.runAsync.

Steve C

unread,
Aug 26, 2012, 2:13:42 PM8/26/12
to google-we...@googlegroups.com


On Sunday, August 26, 2012 1:43:09 PM UTC-4, Thomas Broyer wrote:
You should ask on https://groups.google.com/d/forum/google-gin as the GWT Compiler is not involved in these decisions, only the GIN generator.

BTW, what's the error? Does it work if you don't use an AsyncProvider? (direct injection, or through a Provider)

And as a workaround / alternative, I suppose you could use a "@Special Provider<DiSecondary>" and an explicit GWT.runAsync.


I'll repost the original question there.

In the meantime:

1. It works fine without the AsyncProvider.

2. The error the compiler gives is:
[ERROR] No implementation bound for "Key[type=com.x.dep_inj.client.DiSecondary, annotation=@com.x.dep_inj.client.Async]" and an implicit binding cannot be created because the type is annotated.
3. Thanks for the suggestion about the Provider. I had tried something along those lines, but couldn't figure out a way to get the callback to it. But, I've got a few more ideas on that now that are worth trying.

Message has been deleted

Steve C

unread,
Aug 27, 2012, 12:30:05 PM8/27/12
to google-we...@googlegroups.com
Well, I have to apologize - I have it working now, although I don't think I actually changed anything related to the problem.  FYI, the error message I printed was incorrect and not the cause of the problem - the actual annotation I was using was indeed @Async and not @Special, which I changed in the code examples I gave to avoid any implication that it wasn't just a made-up annotation.

As an aside, I also got a Provider version working, which was a pretty ugly, and not something that seems easily reusable. I ended up creating a proxy class that wrapped an instance of the class I wanted (and implemented the same interface), passed all the methods through to the contained object, then added another method to kick off the runAsync call.  Two things I don't like about that approach are:
  • I ended up explicitly instantiating my class in the runAsync call, which seems to render some of the injection concept moot
  • because of my additional method to load the proxy, I either had to add that to my base interface, or typecast what I got from the provider, to the proxy class, in order to invoke it.  I chose the latter.

Reply all
Reply to author
Forward
0 new messages