2016-02-23 4 views
0

Я пытаюсь поддержать сторонние расширения, используя многострочные карты, но я не могу окутать голову, как он должен обеспечить расширяемую инфраструктуру. Похоже, это должно быть очень просто, но Dagger 2 documentation on multibindings на самом деле не представляет пример того, как это сделать. Я хочу, чтобы другие разработчики могли писать собственные реализации интерфейса, который я предоставляю, а затем легко интегрировать.Как использовать инъекцию поля с помощью многосвязного инструмента Dagger 2?

Вот пример кода, который показывает, что я пытаюсь сделать:

// This is the interface that third parties can implement. 
public interface FooService { 
    public void run(); 
} 

// This is the default implementation of the interface that I provide. 
class DefaultFooImpl implements FooService { 
    DefaultFooImpl() { ... } 
    @Override public void run() { ... } 
} 

// Third parties would need to add their own modules to provide their 
// implementations of FooService on different keys (right?). 
@Module class DefaultImplModule { 
    @Provides(type = MAP) 
    @StringKey("default") 
    static FooService provideDefaultImpl() { 
    return new DefaultFooImpl(); 
    } 
} 

// PROBLEM! This won't work for third-party implementations, since I 
// can't include their modules here because I don't know them. 
@Component(modules = DefaultImplModule.class) 
interface FooServiceComponents { 
    Map<String, FooService> fooServices(); 
} 

public class FooDispatcher { 
    // PROBLEM! How do I actually inject this map? Does this work? 
    @Inject Map<String, FooService> fooServices; 

    void callFooService(String whichService) { 
    // whichService is any of the Strings in the combined services map. 
    // For the default implementation, you'd pass in "default". 
    this.fooServices.get(whichService).run(); 
    } 
} 

Так что недостающий элемент, который связывает все это вместе и фактически делает его работу? Благодарю.

+0

Чтобы ответить на ваш вопрос: «Как я на самом деле придать эту карту? Это работает? »: Да. – philo

+0

Ваш код выглядит правильно. Вы спрашиваете, как вы будете вводить больше записей на карте развязанным способом? Вы можете вводить записи в любой модуль приложения. Потребителю карты не нужно ссылаться на них, но приложение должно установить модули (как и любая другая зависимость). – philo

ответ

1

Вот шаблон, который я использую - модуль должен быть настроен во время использования компоновщика компонентов путем передачи ваших аргументов. Настоятельно рекомендую щадя использование и только в случае необходимости - все должно быть так просто, как вам нужно, чтобы они были, но не больше :-)

@Module 
class ConfigurableModule { 

    private IDependencyOne one; 
    private IDependencyTwo two; 
    ... 

    ConfigurableModule() { 

    } 

    ConfigurableModule(IDependencyOne one, IDependencyTwo two, ...) { 
     this.one = one; 
     this.two = two; 
    } 


    @Provides IDependencyOne getIDependencyOne(MyIDependencyOneImpl impl) { 
     return one == null ? impl : one; 
    } 

    @Provides IDependencyTwo getIDependencyTwo(MyIDependencyTwoImpl impl) { 
     return one == null ? impl : one; 
    } 
} 
Смежные вопросы