0

We have a core Java application and different plugins for different clients. We are using Hk2 for dependency injection.

I would like to now is it possible to have a way of putting some @Named Qualifier names to properties files of plugins so I can just change the value of the property file to inject different class implementations for different clients.

What I mean is having @Named(key="plugins.impl.xplugin") rather than @Named("XPlugin").

This would help a lot to get rid of so much boilerplate code for plugins.

N.B.BASARAN
  • 86
  • 1
  • 7
  • Can you give a little bit more detail about what you want to happen? It's not completely clear to me how you want this system to work. – Paul Samsotha Sep 10 '20 at 14:43
  • Sure. Let's say I have a base application with two different clients. For a ServiceA I currently implement ServiceImpA and ServiceImpB classes to inject client-specific implementations of some functions. But they are currently just boilerplate code. I would like to have a common interface and a property file driven implementation so I can inject different implementations of Service A for different clients. I am not sure if this is enough or I may try to draw some detailed chart to be more clear. – N.B.BASARAN Sep 10 '20 at 15:40
  • 1
    Sounds like you're asking for something that is outside the scope of the injection system. You will probably have to implement this yourself. Conditional binding isn't so hard to implement. That's pretty much what you're looking for it sounds like. – Paul Samsotha Sep 10 '20 at 16:04
  • Thing is injection is done on runtime. It really feels like possible to decide which implementation will be injected by reading the classpath of implementation from a external property file. – N.B.BASARAN Sep 10 '20 at 16:32
  • 1
    Have you ever heard of the [ServiceLoader](https://docs.oracle.com/javase/9/docs/api/java/util/ServiceLoader.html)? Maybe you are looking for something like this? When you say _"reading the classpath of implementation from a external property file"_, this is the first thing that comes to mind. A lot of "plugin" systems actually use this. [See also](https://docs.oracle.com/javase/tutorial/ext/basics/spi.html) – Paul Samsotha Sep 10 '20 at 16:45
  • That really looks like what I was searching for. I will try and share the results with you. Thanks – N.B.BASARAN Sep 10 '20 at 17:01

1 Answers1

0

This is a possible solution for you using IterableProvider (which has a "named" method on it to choose a specific named version at runtime):

@Service
public class Example {
    
    @Inject
    private IterableProvider<MyService> myService;
    
    public MyService getSpecificService(String serviceName) {
        return myService.named(serviceName).get();
    }

    @Contract
    public interface MyService {}
    
    @Service @Named("Foo")
    public static class MyServiceFoo implements MyService {}
    
    @Service @Named("Bar")
    public static class MyServiceBar implements MyService {}

}

In the example above you just pass the name of the service you want ("Foo" or "Bar") to getSpecificService and it will pass back the implementation of your choice.

Note real code would probably want to be more sophisticated about what happens if there is no implementation of the given name for the given service.

jwells131313
  • 2,364
  • 1
  • 16
  • 26