I have a Factory Class use case I want to implement with Guice, but not sure how. I have an Abstract Class named Action which represent different kind of actions the user could perform on my app. Each of the Actions are subclasses of Action class, and each of them also have an identification of String type. Because Actions are heavy objects I don't want to have it all instanciated at once, so I provides a Factory to instanciate each of them depending on the ID the client ask for.
The Factory Interface looks like:
public interface ActionFactory {
Action getActionByID(String id);
}
Our implementation of this Factory uses a HashMap to maintain the relationship between the String instance and a so called ActionInstantiator that will provides the concrete Action instance. Implementation of this looks like:
public class ActionFactoryImpl implements ActionFactory {
private HashMap<String, ActionInstantiator> actions;
private static ActionFactoryImpl instance;
protected ActionFactoryImpl(){
this.actions=new HashMap<String, ActionInstantiator>();
this.buildActionRelationships();
}
public static ActionFactoryImpl instance(){
if(instance==null)
instance=new ActionFactoryImpl();
return instance;
}
public Action getActionByID(String id){
ActionInstantiator ai = this.actions.get(id);
if (ai == null) {
String errMessage="Error. No action with the开发者_高级运维 given ID:"+id;
MessageBox.alert("Error", errMessage, null);
throw new RuntimeException(errMessage);
}
return ai.getAction();
}
protected void buildActionRelationships(){
this.actions.put("actionAAA",new ActionAAAInstantiator());
this.actions.put("actionBBB",new ActionBBBInstantiator());
.....
.....
}
}
So some client that could use this factory and wants ActionAAA instance class calls it like this:
Action action=ActionFactoryImpl.instance().getActionByID(actionId);
Where actionId was obtained at runtime from database.
I found that some kind of annotation injection could do something similar, but in my case I think that that wouldn't work, because I only know the instance that the user will requieres at runtime, so I couldn't annotated on the code.
I'm new to Guice so maybe this is something very common I couldn't found in the docs, I appologies if that is the case. Any help will be appreciated. Regards Daniel
You want to use the Multibindings extension, specifically MapBinder. You probably want your ActionInstantiator
type to implement Provider<Action>
. Then you can do:
MapBinder<String, Action> mapbinder
= MapBinder.newMapBinder(binder(), String.class, Action.class);
mapbinder.addBinding("actionAAA", ActionAAAInstantiator.class);
// ...
Then you can inject a Map<String, Provider<Action>>
where you want. You'll also be able to inject things in to your ActionInstantiator
s.
精彩评论