Как получить все разработчики / подклассы интерфейса с Guice? - PullRequest
17 голосов
/ 22 мая 2011

С помощью Spring вы можете определить свойство массива и сделать так, чтобы Spring вставлял один из каждого (@Component) класса, производного от данного типа.

Есть ли эквивалент для этого в Guice?Или точка расширения, чтобы добавить это поведение?

Ответы [ 2 ]

15 голосов
/ 24 мая 2011

Это похоже на случай использования Guice MultiBinder . Вы можете получить что-то подобное:

interface YourInterface {
    ...
}

class A implements YourInterface {
    ...
}

class B implements YourInterface {
    ...
}

class YourModule extends AbstractModule {
    @Override protected void configure() {
        Multibinder.newSetBinder(YourInterface.class).addBinding().to(A.class):
        Multibinder.newSetBinder(YourInterface.class).addBinding().to(B.class):
    }
}

И вы можете ввести Set<YourInterface> в любом месте:

class SomeClass {
    @Inject public SomeClass(Set<YourInterface> allImplementations) {
        ...
    }
}

Это должно соответствовать тому, что вам нужно.

11 голосов
/ 12 ноября 2016

Guice Multibindings требует явного добавления addBinding () для A & B в YourInterface.Если вам нужно более «прозрачное» (автоматическое) решение, такое как то, что AFAIK Spring предлагает «из коробки», тогда предположим, что Guice уже знает о A & B, потому что у вас уже есть привязка для A & B в другом месте, в любом случае, даже если не явное, а просто неявное, например, через @Inject где-то еще, тогда и только тогда вы, альтернативно, можете использовать что-то подобное для автообнаружения (, вдохновленное тем, что сделано здесь , основанный на доступе к инжектору Guice в модуле ):

class YourModule extends AbstractModule {
   @Override protected void configure() { }

   @Provides
   @Singleton
   SomeClass getSomeClass(Injector injector) {
       Set<YourInterface> allYourInterfaces = new HashSet<>();
       for (Key<?> key : injector.getAllBindings().keySet()) {
           if (YourInterface.class.isAssignableFrom(key.getTypeLiteral().getRawType())) {
            YourInterface yourInterface = (YourInterface) injector.getInstance(key);
            allYourInterfaces.add(yourInterface);
       }
       return new SomeClass(allYourInterfaces);
   }
}

Обратите внимание, что этот подход НЕ требует сканирования пути к классам;он просто смотрит на все уже известные привязки в Инжекторе для всего, что IS-A YourInterface.

...