如果一个对象(让我们称之为 workController )包含一个字符串到处理程序的地图( Map<String, Handler> handlerMap
),它将使用Guice模块中的mapBinder和其他也注入的实例变量。现在,如果我想在我的代码中实例化workController(让我们说我正在创建一个依赖于 workController workConsumer : workConsumerProvider 的提供程序>因此我需要实例化this并将workController提供给workConsumer的构造函数),我应该再次声明整个映射并将其传递给workController的构造函数,还是有其他方法可以解决这个问题?
考虑WorkController.java:
public class WorkController implements ActivityController {
private ObjectMapper objectMapper;
private final Map<String, Handler> handlerMap;
@Inject
public WorkController(final ObjectMapper objectMapper,
final Map<String, Handler> handlerMap) {
this.objectMapper = objectMapper;
this.handlerMap = handlerMap;
}
public void control() {
//call the handler = getHandler(string usecase)
//call the handler.handle()
}
public Handler getHandler(String useCase) {
Handler handler = eventHandlerMap.get(useCase);
return handler;
}
为了支持工作控制器的DI,我已经为ObjectMapper定义了提供程序,如下所示:ObjectMapperProvider.java
public class ObjectMapperProvider implements Provider<ObjectMapper> {
@Override
public ObjectMapper get() {
final ObjectMapper mapper = new ObjectMapper();
return mapper;
}
}
使用MapBinder将地图注入相应的Guice模块内,如下所示:
public class WorkConsumerModule extends AbstractModule {
@Override
protected void configure() {
bind(WorkConsumer.class).toProvider(WorkConsumerProvider.class);
bind(ObjectMapper.class).toProvider(ObjectMapperProvider.class);
final MapBinder<String, handler> mapBinder = MapBinder.newMapBinder(binder(),
String.class, handler.class);
//other bindings for the subject and events to be added here.
mapBinder.addBinding(UseCaseOne.toString()).to(HandlerImplOne.class);
mapBinder.addBinding(UseCaseTwo.toString()).to(HandlerImplTwo.class);
}
}
现在,考虑一下WorkConsumer.java
public class WorkConsumer {
@Inject
public WorkConsumer(final String instanceVariableOne,
final String instanceVariableTwo,
final String instanceVariableThree,
final WorkController workController) {
final FailureHandler failureHandler = new FailureHandlerImpl();
final Consumer consumer = new Consumer(instanceVariableOne, instanceVariableTwo, instanceVariableThree, workController, failureHandler);
consumer.start();
}
}
现在,为了为此 WorkConsumer 注入实例变量字符串,我们创建了一个 WorkConsumerProvider 类:WorkConsumerProvider.java
public class WorkConsumerProvider implements Provider<WorkConsumer> {
@Override
public WorkConsumer get() {
final WorkConsumer workconsumer
= new WorkConsumer(getInstanceVariableOne(),
getInstanceVariableTwo(),
getInstanceVariableThree(),
getWorkController());
return workconsumer;
}
private String getInstanceVariableOne() {
//return these values based on configs.
}
private String getInstanceVariableTwo() {
//return these values based on configs.
}
private String getInstanceVariableThree() {
//return these values based on configs.
}
//This is the place where I have a doubt.
private WorkController getWorkController() {
//Should I declare a new map and populate it again in order to instantiate workController despite having populated it once inside the guice module workConsumerModule.java ?
//I haven't yet populated it here.
return new WorkController(new ObjectMapper(), new HashMap<String, Handler>());
}
}
答案 0 :(得分:1)
您可以注入您的Providers,这样您就可以注入一个完全构造和实例化的WorkController。
public class WorkConsumerProvider implements Provider<WorkConsumer> {
private final WorkController controller;
@Inject
WorkConsumerProvider(WorkController controller) {
this.controller = controller;
}
@Override
public WorkConsumer get() {
return new WorkConsumer(
/* instance variables */,
controller
);
}
//Your instance variables
}
这会导致每个WorkConsumer
共享WorkController
。
如果您希望每个人都有一个唯一的WorkController
,您可以将实例变量更改为Provider<WorkController>
并注入它。然后在controllerProvider.get()
中使用WorkConsumerProvider#get()
。
Guice's wiki有很多好的信息,包括针对不同场景的最佳做法和示例。