How to tersely define Guice bindings of parametrised classes using Xtend?
-
04-03-2021 - |
Domanda
The following Java code sets up a Guice binding. It uses an anonymous subclass of AbstractModule
that provides an implementation of configure
to set the bindings, and anonymous subclasses of TypeLiteral
to create a binding of Map
to HashMap
for specific type parameters (as described here).
injector = Guice.createInjector(new AbstractModule() {
@Override protected void configure() {
bind(new TypeLiteral<Map<String, Event>>() {})
.to(new TypeLiteral<HashMap<String, Event>>() {});
}
});
How could I write this in Xtend?
As far as I can see, Xtend doesn't support implementing anonymous classes or nested classes (they aren't mentioned in the doc and I haven't been able to guess a working syntax). So I would have to define my AbstractModule
and each of my TypeLiteral
implementations in separate Xtend files... not very terse. Am I missing an Xtend or a Guice trick to make this work well?
Soluzione
You could use a closure to implement the module interface:
injector = Guice.createInjector [ bind(typeof(SomeType)).to(typeof(AnImplementation)) ]
However, this will not solve the problem for the type literals. You'd have to use Java for that one, but I think it will not hurt.
Altri suggerimenti
what about intoducing a real class instead of a anonymous inner one?
On a related note, you can use an Xtend closure to implement Guice's Provider interface.
For example, calling IResourceScopeCache.get in Java:
@Inject
private IResourceScopeCache cache;
public EvaluatedResource getEvaluatedResource(EObject object) {
final Resource resource = object.eResource();
return cache.get("key", resource, new Provider<Object>() {
public Object get() {
return evaluate(resource);
}
});
}
public EvaluatedResource evaluate(Resource resource) {
...; // create EvaluatedResource evaluatedResource
return evaluatedResource; // return it
}
in Xtend becomes:
@Inject
IResourceScopeCache cache
def getEvaluatedResource(EObject object) {
val resource = object.eResource
cache.get("key", resource, [|evaluate(resource)])
}
def evaluate(Resource resource) {
... // create EvaluatedResource evaluatedResource
evaluatedResource // return it
}
The trick is that [|...]
is a function with zero parameters, in this case Provider.get()
.