Hi Uemit,

I like your question and must say that I've personally run quite a few times 
into the "deferred binding" vs "injection" question. My personal take on 
this is that I always favor injection, unless the binding should be 
property-dependent. By property-dependent I mean that the binding depends on 
any of the "deferred property" defined in my .gwt.xml. Typically: browser or 
language. The reason I prefer injection is because it's more powerful: it 
allows for non-default constructor and will inject the newly created class.

When you really have to use deferred binding, I see three cases:

1) Your implementations have no dependencies.
This is the easy case. Just call GWT.create(BaseInterface.class), or @Inject 
BaseInterface and rely on Gin calling GWT.create, and use <replace-with> as 
you did.

2) Your implementations have dependencies that need to be @Inject-ed
It gets trickier and I have never done it. One approach I might use would be 
to statically inject the ginjector in the abstract class and use it to fetch 
dependencies. Alternatively, you could statically inject the dependencies 
themselves (although in that case, if the dependencies are different for 
each implementation, you will have to statically inject all the 
implementations, even the ones you don't use, which is wasteful). 

I think you fall exactly in this category: the "url" is probably an 
application-wide resource that you want to inject into your HttpDataSource 
(if it's not, I agree with Brian Reilly: your two DataSource have different 
APIs and cannot be created interchangeably: when creating HttpDataSource the 
user needs to specify a URL, not when creating other types of DataSource.)

3) Your implementation needs some per-instance parameters (i.e. they would 
use a Gin assisted factory)
Here, the key is to perform the deferred binding on a factory instead of the 
type itself. For example:

public interface FormattedDateFactory {
    FormattedDate create(Date date);
}

public class EnglishFormattedDateFactory {
    public FormattedDate create(Date date) {
      return new EnglishFormattedDate(date);
    }
}

public class ChineseFormattedDateFactory {
    public FormattedDate create(Date date) {
      return new ChineseFormattedDate(date);
    }
}

<replace-with class="EnglishFormattedDateFactory">
    <when-type-is class="FormattedDateFactory" />
</replace-with>
<replace-with class="ChineseFormattedDateFactory">
    <when-type-is class="FormattedDateFactory" />
    <when-property-is name="locale" value="zh"/>
</replace-with>


If you need to inject dependencies in your factories (or your FormatedDate 
implementations) then you will need to use one of the trick of (2).

- - - - - - -

By the way, I'm working on much better way of mixing deferred binding and 
dependency injection. If you're interested, star this issue in Gin:
  http://code.google.com/p/google-gin/issues/detail?id=142

Hope it helps!

    Philippe

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to google-web-toolkit@googlegroups.com.
To unsubscribe from this group, send email to 
google-web-toolkit+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

Reply via email to