我希望能够通过辅助注入发现/注入创建对象的方法的名称到创建的对象中。
我想做的一个例子:
// what I want guice to create the implementation for this
interface Preferences {
Preference<String> firstName();
Preference<String> lastName();
// other preferences possibly of other types
}
// my interfaces and classes
interface Preference<T> {
T get();
void set(T value);
}
class StringPreference implements Preference<String> {
private final Map<String, Object> backingStore;
private final String key;
@Inject StringPreference(@FactoryMethodName String key,
Map<String, Object> backingStore) {
this.backingStore = backingStore;
this.key = key;
}
public String get() { return backingStore.get(key).toString(); }
public void set(String value) { backingStore.put(key, value); }
}
// usage
public void exampleUsage() {
Injector di = // configure and get the injector (probably somewhere else)
Preferences map = di.createInstance(Preferences.class);
Map<String, Object> backingStore = di.createInstance(...);
assertTrue(backingStore.isEmpty()); // passes
map.firstName().set("Bob");
assertEquals("Bob", map.firstName().get());
assertEquals("Bob", backingStore.get("firstName"));
map.lastName().set("Smith");
assertEquals("Smith", map.lastName().get());
assertEquals("Smith", backingStore.get("lastName"));
}
不幸的是,我到目前为止实现这一目标的唯一方法是
我正在寻找一个解决方案:
答案 0 :(得分:0)
关于注入创建上下文的真实请求is not possible and will not be possible in Guice。 (direct link to bug)
其他一些想法:
如果您的用例足以使用只读属性,请使用Names.bindProperties
,这将允许整个Properties
实例(或Map<String, String>
)绑定到常量适当的@Named
注释。与其他bindConstant
调用一样,这甚至会为您或您使用convertToTypes
绑定的任何其他内容强制转换为适当的原始类型。
如果您只是为每个注射课程寻找一个单独的地图,请不要忘记您可以自己编写工厂。
class PreferenceMapOracle {
private static final Map<Class<?>, Map<String, String>> prefMap =
Maps.newHashMap();
public Map<String, String> mapForClass(Class<?> clazz) {
if (prefMap.contains(clazz)) {
return prefMap.get(clazz);
}
Map<String, String> newMap = Maps.newHashMap();
prefMap.put(clazz, newMap);
return newMap;
}
}
class GuiceUser {
private final Map<String, String> preferences;
@Inject GuiceUser(PreferenceMapOracle oracle) {
preferences = oracle.mapForClass(getClass());
}
}
Guice中内置的任何内容都不会自动反映在您的Preferences
界面上,并且在没有任何内容的情况下创建一个bean样式的实现。你可以用自由使用dynamic proxy objects编写自己聪明的框架,或者用一个提供漂亮反射支持的软件包,如GSON。你仍然需要以这种或那种方式提供那些反射创建的接口,但我可以很容易地想象一下这样的调用:
preferences = oracle.getPrefs(Preferences.class);