Dagger-2:如果我必须在运行时注入依赖项,如何连接程序?

时间:2018-09-18 13:35:25

标签: java dependency-injection dagger-2

我认为这是一个非常基本的问题,我找不到答案。我的设置如下:

我的主要组件(用于使依赖关系可用于整个对象图,例如ModuleUtils.class提供的Jackson的ObjectMapper.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();
    }
}

在程序运行时,会产生套接字,并可以借助Dagger2实例化新的SocketManager:

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依赖关系吗?
那么,如何在初始化阶段连接整个程序并使用dagger的继承概念?还是在运行时需要注入依赖项时如何避免中断整个程序的接线过程?

1 个答案:

答案 0 :(得分:0)

当您的父组件具有对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);
    }
}

另请参阅Dagger Subcomponents