rodionmoiseev / c10n

A Java library, focused on making internationalisation more modular, easier to evolve and maintain, robust-to-change and IDE-friendly without excess of external tools.
Apache License 2.0
67 stars 10 forks source link

Calling C10N.configure(...) multiple times #21

Closed paolofulgoni closed 10 years ago

paolofulgoni commented 10 years ago

If C10N is used in a library, I think that the C10N.configure(...) function must be called from the lib itself. For example, the lib could use the default annotations.

Now, If C10N is used also in a project, which in turn is using the above mentioned library, another call to C10N.configure(...) can change the configuration. For example, custom annotations may be set.

I haven't made any test, but it seems to me that this could be an issue. Am I missing anything?

rodionmoiseev commented 10 years ago

Thanks. If you mean calling C10N.configure() and also C10N.get(Class) from multiple libraries, then there will be a problem. The static methods in C10N are for convenience, to simplify usage from a single library (the typical case). If you wish to use c10n from multiple libraries in one JVM you will need to do one of the below:

  1. Store C10NMsgFactory for each library in your own (static) variable, for example:
//set-up for one library
C10N.configure(...);
MyC10N.factory = C10N.getRootFactory();

//usage from that library
MyC10N.factory.get(MyMessagesInterface.class);
  1. Jarjar C10N into your library before including it into your other project that also uses C10N
paolofulgoni commented 10 years ago

Thank you for your prompt reply. Solution 1 looks much more clean to me.

What about adding another get method which takes also a configuration?

public static <T> T get(C10NConfigBase conf, Class<T> c10nInterface)

This way I would store the configuration in a (static) variable only if different from the default one.

rodionmoiseev commented 10 years ago

I don't really see the advantage, since you would have to hold on to your conf (probably also in a static variable), so that you can pass it each time you call get(conf, interface). So calling C10N.get(MyC10N.conf, MyInterface.class) does not seem any more convenient than doing MyC10N.factory.get(MyInterface.class) (or more simply MyC10N.get(MyInterface.class)).

Or maybe I misunderstood you?

paolofulgoni commented 10 years ago

Yes, you're right, forget the last line of my previous comment.

But please consider this example:

C10N is used by a MainProject and by one of its dependencies Lib1.

MainProject uses the C10N static methods C10N.configure(...) and C10N.get(...) in the standard way.

Lib1 may then use C10N.configure(...), C10N.getRootFactory() and then MyC10NFactory.get(...) as you suggested. But what if the call to C10N.configure(...) happens after the one made by MainProject? I think that in this case any subsequent calls to C10N.get(...) in MainProject would use the wrong configuration.

In that case a static function C10N.get(conf, c10nInterface) which doesn't change the "actual" configuration would solve the issue.

rodionmoiseev commented 10 years ago

I see your point. Actually, you could get around the problem by instantiating C10NMsgFactory for Lib1 in this way:

C10NCoreModule module = new C10NCoreModule();
C10NMsgFactory myFactory = module.defaultC10NMsgFactory(module.resolve(conf));

But I would agree it is not obvious for a user. So I would suggest creating a static utility method C10N.createMsgFactory(C10NConfigBase conf) that would do the above and return the factory, without touching any of the static variables.

paolofulgoni commented 10 years ago

C10N.createMsgFactory(C10NConfigBase conf) would be perfect. For the moment I'll use the code snippet that you suggested.

Thank you for your support