0

I have a bunch of classes implementing an interface Job. Each of these classes have an annotation @Work(name="the corresponding name")

Each of those classes have different private fields which are injected using guice during construction. Now I want to create a mapping Map reading a config file which is something like this

- name: "test1"
  worker_annotation = "annotation1"
- name: "test2"
  worker_annotation = "annotation2"
- name: "test3"
  worker_annotation = "annotation3"

So what this module needs to do is read this config file, get all the classes annotated with @Work annotation and create a map Map where the key string is corresponding to the name in the config file and Job is the corresponding class implementing the Job interface and being annotated with the corresponding Worker annotation.

user12331
  • 486
  • 7
  • 22
  • 2
    reading the config file won't be the issue I guess, you'll get the classes [using reflection](https://stackoverflow.com/a/13128882/1428369). You get the annotation using `c.getClass().getAnnotations()` and can dissect it like shown [here](https://www.geeksforgeeks.org/method-class-getannotation-method-in-java/). But I've the suspicion that guice might support such stuff in some way. – Curiosa Globunznik Dec 12 '19 at 02:04
  • What is the end use case of this? Are you using the map to get the class and then create an instance? Or do you want the map to already have the injected instance available? – kendavidson Dec 27 '19 at 19:15

1 Answers1

0

The solution I'm going to provide has the constraint that it only works if all your job classes are of a different type (= class) and I suppose that it is the case as far as I can assume it from your description. Otherwise you would need to introduce keys so that same types are distinguishable for Guice.

Your example sounds like a job for the MapBinder of Guice's multibindings extension.

I could think of something like the following code (untested):

// code in some Guice module configure() method
...
SomeConfig config = loadConfig(); // I invented this config code. Adapt!
...
MapBinder<String, Job> mapbinder
     = MapBinder.newMapBinder(binder(), String.class, Job.class);
for(String name : config.allNames()) {
     String workerName = config.lookUpWorkerName(name); // not Guice-related
     Class<?> clazz = lookUpJobClassFromAnnotationName(workerName); // not Guice-related either
     mapbinder.addBinding(name).to(clazz); // name must be unique
}

Then in some other class you can inject the Map<String, Job> and it contains for each key the corresponding class instance.

Further reading about Guice and configuration

I had a similar use case although more complex instantiating a dependency graph that varies depending on the configuration. I summed it up in a document if you're interested and compare my use case with yours.

Ewald Benes
  • 622
  • 6
  • 13