0

我希望能够通过辅助注入到创建的对象中发现/注入创建对象的方法的名称。

我想做的一个例子:

// 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"));
}

不幸的是,到目前为止,我想到的唯一方法是

  1. 扩展辅助注入(通过复制和粘贴)以添加我的功能
  2. 写一些非常类似于为我做的辅助注射的东西
  3. 编写很多样板文件,在没有 guices 帮助的情况下做到这一点

我正在寻找以下方面的解决方案:

  1. 执行此操作的一些 guice 配置或模式
  2. 一些这样做的扩展
  3. 我可以查看的文档/示例将帮助我自己编写此内容
  4. 示例应用程序的替代模式来完成我想做的事情
4

1 回答 1

0

您关于注入创建上下文的真正请求在 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);
    
于 2012-12-17T23:59:32.140 回答