2016-05-17 2 views
1

У нас есть набор интерфейсов, например BookingInterface, InvoiceInterface, PaymentInterface, которые реализуются различными бизнес-процессамисистема плагинов Modular Java с помощью Guice

например

Business1BookingInterface implements BookingInterface { 
} 
Business1InvoiceInterface implements InvoiceInterface { 
} 
Business2BookingInterface implements BookingInterface { 
} 
Business2InvoiceInterface implements InvoiceInterface { 
} 

Мы смотрим на то, чтобы каждый бизнес-процесс плагин, который реализует набор интерфейсов.

В нашем остальное API мы хотели бы конкретный интерфейс плагина вводится в нашу службу

например

@Inject 
public BillingService(Configuration configuration, 
         EventDispatcher eventDispatcher, 
         Map<String,PluginInterface> theCorrectInterfaceImplementation) { 

}

Я отрываясь MapBindings, AssistedInjection и FactoryModuleBuilder, но не уверен, как в как мне получить правильную настройку Guice, чтобы внедрить необходимый интерфейс плагина во время выполнения.

ответ

2

MapBinder (как одна из функций Multibindings) - это правильный вызов для интерфейса с плагином. FactoryModuleBuilder - это деталь реализации Assisted Injection, которая представляет собой просто путь к смежным явным параметрам конструктора с параметрами конструктора Guice, предоставленными. Если вам не нужно это делать, вам не нужна вспомогательная инъекция.

Вам все еще нужно настроить эти привязки в модуле:

public Business1Module extends AbstractModule { 
    @Override public void configure() { 
    MapBinder<String, BookingInterface> bookingBinder = 
     MapBinder.newMapBinder(binder(), String.class, BookingInterface.class); 
    bookingBinder.addBinding("business1").to(Business1BookingInterface.class); 
    MapBinder<String, InvoiceInterface> invoiceBinder = 
     MapBinder.newMapBinder(binder(), String.class, InvoiceInterface.class); 
    invoiceBinder.addBinding("business1").to(Business1InvoiceInterface.class); 
    } 
} 

..., а затем установить этот модуль в вашем инжектором.

Injector yourInjector = Guice.createInjector(/*...*/, 
    new Business1Module(), new Business2Module()); 

Получается, что вам не нужно агрегировать эти зависимости сами, и что Guice не будет жаловаться на нескольких конфликтующих привязок к Map<String, BookingInterface> или Map<String, InvoiceInterface> (и т.д.) ... они будут автоматически объединены в один большая карта каждая.

Другие ноты:

  1. Multibindings находится в отдельном JAR, так что не забудьте установить, что на вашем пути к классам.

  2. Это может быть отличный повод использовать Modules with constructor parameters:

    Injector yourInjector = Guice.createInjector(/*...*/, 
    new BusinessModule("business1", 
        Business1BookingInterface.class, Business1InvoiceInterface.class), 
    new BusinessModule("business2", 
        Business2BookingInterface.class, Business2InvoiceInterface.class)); 
    
+0

Могу ли я использовать поставщиков вместе с MultiBinding? чтобы избежать круговых зависимостей? – user160108

+1

Я ввел услуги, используя провайдер. Карта invoiceMap, и все работает хорошо. Больше круговых зависимостей. – user160108