Dagger-2: Как подключить мою программу, если мне нужно внедрить зависимости во время выполнения? - PullRequest
0 голосов
/ 18 сентября 2018

Я думаю, что это очень фундаментальный вопрос, на который я не смог найти ответ.Моя установка выглядит следующим образом:

Мой основной компонент (используется для того, чтобы сделать зависимости доступными для всего графа объектов, например, ObjectMapper.class Джексона, который предоставляется ModuleUtils.class)

@Component(modules = {
    ModuleApplication.class,
    ModuleUtils.class
})
public interface ComponentApplication {
   ComponentSocketManager.Builder componenetSocketManagerBuilder();
}

Мой субкомпонент (используется для создания SocketManager)

@Subcomponent(modules = ModuleSocketManager.class)
public interface ComponentSocketManager {

   //Subcomponent is used to create a SocketManager
   SocketManager socketManager();

   @Subcomponent.Builder
   interface Builder {

    //SocketManager requires a Socket to work with, which is only 
    //available at runtime
    @BindsInstanceBuilder socket(Socket socket);
    ComponentSocketManager build();
    }
}

Во время выполнения программы создаются сокеты и создаются новые SocketManager с помощью Dagger2:

Socket socket = this.serverSocket.accept();
//Here the wiring of the object graph is somehow interrupted, as I need
//to inject objects at runtime, that are required for the wiring process
SocketManager sm = DaggerComponentApplication.create()
                     .componenetSocketManagerBuilder()
                     .socket(socket) //inject the socket at runtime
                     .build()
                     .socketManager();

//I don't want to wire my app manually. Dagger should do the wiring of the
//entire object graph, not only up to the point where I inject at runtime
AppBusinessLogic appBusinessLogic = ... //some deeply nested wiring
MyApp app = new MyApp(sm, appBusinessLogic);
Thread thread = new Thread(app);   //new thread for every client
thread.start();

Проблема в том, как я вручную вмешиваюсь в «процесс подключения» dagger2 и как создается AppBusinessLogic.AppBusinessLogic в основном представляет всю программу и представляет собой глубоко вложенный граф объектов.
Что я хочу:
Инициализировать всю программу при запуске (без «прерывания» процесса подключения).Скорее, вставьте зависимости во время выполнения в законченный граф объектов, который содержит своего рода «заполнители» для зависимостей времени выполнения.
Зачем мне это нужно?
Я хочу повторно использовать зависимости от родительских компонентов.Например, в приведенном выше примере ComponentApplication имеет ObjectMapper-зависимости.Как я могу использовать этот экземпляр для моего объекта appBusinessLogic?Конечно, я мог бы иметь что-то вроде ComponentAppBusinessLogic, который наследуется от ComponentApplication.Однако использование ComponentAppBusinessLogic для создания «appBusinessLogic» -объекта приведет к новой зависимости ObjectMapper?
Итак, как мне связать всю программу на этапе инициализации и использовать концепцию наследования кинжала?Или как избежать прерывания процесса разводки всей программы, когда у меня есть зависимости во время выполнения для внедрения?

1 Ответ

0 голосов
/ 19 сентября 2018

Если ваш родительский компонент имеет привязку для ObjectMapper, тогда ваш подкомпонент имеет доступ к этому.Это означает, что вы можете создать методы предоставления в своем подкомпоненте, например ...

@Subcomponent(modules = {SubcomponentModule.class})
public interface MySubcomponent {
    ...
    ObjectMapper objectMapper(); // e.g. singleton bound by parent component
    ...
}

, и вы можете зависеть от таких объектов в подкомпонентных модулях

@Module
public class SubcomponentModule {
    @Provides
    Foo provideFoo(ObjectMapper objectMapper) {
        return new Foo(objectMapper);
    }
}

См. Также Подкомпоненты кинжала

...