java - Dagger-2: How to wire up my program, if I have to inject dependencies at runtime?
问题描述
I think this is a very fundamental question, where I couldn't find a answer for. My setup is as following:
My main component (used to make dependencies available to the entire object graph, e.g. Jackson's ObjectMapper.class, that is provided by the ModuleUtils.class)
@Component(modules = {
ModuleApplication.class,
ModuleUtils.class
})
public interface ComponentApplication {
ComponentSocketManager.Builder componenetSocketManagerBuilder();
}
My subcomponent (used to create the 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();
}
}
At runtime of the program, sockets are spawned and new SocketManagers can be instantiated with the help of 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();
The problem is how I manually intervene into the "wiring process" of dagger2 and how AppBusinessLogic is created. AppBusinessLogic basically represents the entire program and is a deeply nested object graph.
What I want:
Initialize the entire program at startup (without "breaking" the wiring process). Rather inject dependencies at runtime into the completed object graph that contains some sort of "placeholders" for the runtime dependencies.
Why do I want that?
I want to reuse dependencies from the parent components. E.g. in the example above ComponentApplication has an ObjectMapper-dependencies. How can I reuse exactly that instance for my "appBusinessLogic" object? Of course I could have sth like a ComponentAppBusinessLogic, that inherits from ComponentApplication. However using ComponentAppBusinessLogic to create a "appBusinessLogic"-object would result into a new ObjectMapper-dependency?
So, how can I wire up the entire program at initialization phase and use dagger's inheritance concept? Or how do I avoid interrupting the wiring process of the entire program when I have dependencies at runtime to inject?
解决方案
当您的父组件具有绑定时,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 子组件
推荐阅读
- c# - 更改后如何获取自动实现属性 C# 6.0 的默认编译时值?
- reactjs - 保存时 React Redux 中的引用项状态未更新
- tomcat - 在 web.xml 中添加 servlet 后,tomcat 404 未发现错误
- python - 当我尝试将 href 添加到导航栏时,Django NoReverseMatch
- unit-testing - 如何测试 Rust 中的可选功能?
- javascript - 将文件内容保存在内存中的变量中
- java - Hibernate:@OneToMany,避免多个 SELECT
- telegram - 是否可以以编程方式预先批准用户加入电报组或频道
- windows-services - 如何修复已下载地图代理 (MapsBroker) 警告 Windows Server 2012 及更高版本?
- matlab - 在matlab中用误差线绘制坐标