I am struggling a little bit with the concept of deferred binding and/or dependency injection in libraries/widgets. I try to come up with the best approach for following problem: I want to implement a visualization widget (composite) that takes in some data and displays it.
I want to separate the way the data is retrieved from the actual visualization part. So I added a generic interface "DataSource" which looks like this:
public interface DataSource {
public void fetch(int start, int end, boolean getFeatures,
DataSourceCallback callback);
}
and I add a setter to my Widget:
public void setDataSource(DataSource source) { this.source = source}
In oder to support http like datasources I also added an abstract class which implements the DataSource Interface and takes an URL in its default constructor:
public abstract class HttpDataSource implements DataSource {
protected String url;
public HttpDataSource(String url) {
this.url = url;
}
}
My specific DataSouce extends this abstract class and implements the fetch method of the interface:
public class MyDataSource extends HttpDataSource {
public MyDataSource(String url) {
super(url);
}
}
This works well. I can create an instance of the MyDataSource class pass it to the setter of my widget. Now I want to make the widget somewhat configurable. I know that this can be done by either Dependency Injection or Deferred Bindings.
So one approach would be to allow the user of the widget to set the DataSource in the Module XML file (similar to the way it is done in the gwt-log library: http://code.google.com/p/gwt-log/source/browse/trunk/Log/src/com/allen_sauer/gwt/log/gwt-log-impl.gwt.xml)
<replace-with class="MyDataSource">
<when-type-is class="DataSource" />
<when-property-is name="source" value="MyDataSourceName" />
</replace-with>
However I don't know if that is possible because by passing a url into the constructor of MyDataSource I have a state and I am not sure how this works with deferred binding. On a side note: would it be possible to have the url also configured in the module's XML file?
I am also worried if people who use this widget/library can implement their own DataSource and pass it to the widget (doesn't it interfere with the deferred binding?)
I suppose another solution would be using dependency injection in the parent application which uses the visualization widget/library ( how can the url be passed, etc? I probably have to inject a Factory?)
Which one of these two solutions is better and in general does it make sense to use deferred binding or GIN to solve this problem?
thanks in advance
Uemit
You should use GIN, not deferred binding. Deferred binding is "is a technique used by the GWT compiler to create and select a specific implementation of a class based on a set of parameters. In essence, deferred binding is the Google Web Toolkit answer to Java reflection." (from Coding Basics) In your scenario, you aren't trying to provide an implementation based on a set of parameters at compile time, but rather runtime.
You can use GIN here in a number of ways. I would suggest having your Widget take via it's constructor the DataSource instance. See the GinTutorial on ways to do that. It does a much better job of explaining it than I can in a few paragraphs.