我希望能够通过向创建的对象中辅助注入来发现/注入创建对象的方法的名称。
我想做的一个例子:
// 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"));
}
不幸的是,到目前为止,我想到的实现这一点的唯一方法是
- 扩展辅助注射(通过复制和粘贴)以添加我的功能
- 写一些与辅助注射非常相似的东西,为我做这件事
- 在没有指导的情况下写很多这样做的样板
我正在寻找一个沿着以下路线的解决方案:
- 一些执行此操作的指导配置或模式
- 某些扩展可以做到这一点
- 我可以查找的地方的文档/示例将帮助我自己写这篇文章
- 示例应用程序的替代模式,以完成我想要做的事情
关于注入创建上下文的真实请求在Guice中是不可能的,也将不可能。(错误的直接链接)
其他几个想法:
-
如果您的用例可以满足只读属性的要求,请使用
Names.bindProperties
,它将允许整个Properties
实例(或Map<String, String>
)绑定到具有适当@Named
注释的常量。与其他bindConstant
调用一样,这甚至会强制转换为适合您的基元类型,或者使用convertToTypes
绑定的任何其他类型。 -
如果您只是在为每个注入类寻找一个单独的Map,请不要忘记您可以编写自己的工厂。
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风格的实现。您可能会编写自己的聪明框架,自由使用动态代理对象,或者使用像GSON这样提供漂亮反射支持的包。您仍然需要以某种方式提供那些反射创建的接口,但我可以很容易地想象这样的调用:preferences = oracle.getPrefs(Preferences.class);