0

I often need a client bundle and some i18n-ed messages in presenters and views.

I would like to know which is the best way to get them : Injection or Singleton?

Solution 1: Up to now, I used to get the messages using a Singleton :

public interface MyMessages extends Messages{

  String key1();
  String key2();
  ...

  class Instance {
    private static MyMessages instance = null;

    public static MyMessages getInstance() {
      if (instance == null) {
       instance = GWT.create(MyMessages.class);
      }
      return instance;
    }
  }
}

FooView.java :

MyMessages.Instance.getInstance().key1();

Solution 2: Would it be better to get it with an injection like this ?

private MyMessages i18n;    

@Inject
public FooView(MyMessages i18n){
  this.i18n=i18n;    
}

The second solution seems cleaner to me but I sometimes get stuck when I need a non-empty constructor which uses some i18n strings:

@Inject
private MyMessages i18n;

public Bar(Foo foo){
  /*
   * do something which absolutely requires i18n here.
   * The problem is that injectable attributes are called
   * after the constructor so i18n is null here.
   */
  foobar();
}
user2147970
  • 412
  • 2
  • 7

1 Answers1

3

First, client bundles and I18N messages, while not singleton themselves, share their state with all their instances, so that once compiled to JavaScript and optimized by the compiler it's as if they were singletons. There are a few corner-case (IIRC, when using the WithLookup variants of I18N interfaces) but generally speaking it doesn't buy you anything explicitly treating them as singletons.

So the question basically becomes whether to use GWT.create() explicitly or have the instance injected. I'd say it's a matter of taste, but also technically GWT.create() doesn't play nice with non-GWTTestCase unit-tests.

Finally, as for your latest question, I suppose that by "non-null constructor" you mean that it takes values that aren't dependencies (i.e. value objects); in which case you should probably use assisted-injection rather than constructing the object yourself and then injecting its members (as an aside: how are you injecting the members then?)

Thomas Broyer
  • 64,353
  • 7
  • 91
  • 164
  • "non-null constructor" => "non-empty constructor", sorry :) – user2147970 Apr 11 '13 at 13:05
  • And what's the problem with injecting the `MyMessages` as a constructor parameter then? (as you did in the `FooView` just above) – Thomas Broyer Apr 11 '13 at 13:18
  • I actually did not know abut assisted injection so I read the google doc about it. Thank you for this, it is very useful in some use cases. That said, using assisted injection for every class that needs i18n or bundles seems heavy. Hence, for this use case, I will keep using GWT.create() :) – user2147970 Apr 15 '13 at 06:54