Guice-根据封闭的类绑定不同的实例 [英] Guice - bind different instances based on enclosing class

查看:73
本文介绍了Guice-根据封闭的类绑定不同的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以基于封闭的类绑定Named实例?例如:在下面的示例中,类A和B将注入DataStore实例.但是,我需要在类A的范围/上下文中将主存储作为StoreA,将辅助存储作为StoreB,但在类B的范围/环境中将主存储作为StoreC,将辅助存储作为StoreD在B类的范围/环境中. >

Is it possible to bind Named instance based on the enclosing class? For ex: in the below sample, classes A and B will get DataStore instance injected. However, I need to have primary store as StoreA and secondary store as StoreB in the scope/context of class A but primary store as StoreC and secondary store as StoreD in the scope/context of class B. How can this be achieved?

class A {
   @Inject
   public A(DataStore dataStore) {
      ... 
   }
}

class B {
   @Inject
   public B(DataStore dataStore) {
      ... 
   }
}

class DataStore {
   @Inject
   public A(@Named("primary") Store primaryStore, @Named("secondary") Store store) {
      ... 
   }
}

bind(Store.class).annotatedWith(Names.named("primary")).to(StoreA.class);//for class A
bind(Store.class).annotatedWith(Names.named("secondary")).to(StoreB.class);//for class A
bind(Store.class).annotatedWith(Names.named("primary")).to(StoreC.class);//for class B
bind(Store.class).annotatedWith(Names.named("secondary")).to(StoreD.class);//for class B

推荐答案

有时称为机器人腿"问题,就像建造一个具有相同腿但左脚和右脚不同的机器人一样.每条腿都绑定一条脚,但是请求的脚取决于请求的腿.在您的情况下,每个数据存储都绑定到主存储和辅助存储,但是哪个存储取决于请求的数据存储.

This is sometimes known as the "robot legs" problem, as if building a robot with identical legs but differing left and right feet. Each Leg to bind a Foot, but the Foot requested depends on the Leg requested. In your case, each DataStore binds to a primary and secondary Store, but which Stores depends on the DataStore requested.

注入Guice的实例无法根据其目标直接绑定(相似功能被拒绝),但常见问题解答中提到的内容,您可以使用 创建类似的效果.

A Guice-injected instance can't be bound directly based on its target (a similar feature was rejected), but as mentioned in the FAQ you can use PrivateModule to create a similar effect.

install(new PrivateModule() {
  @Override public void configure() {
    bind(Store.class).annotatedWith(Names.named("primary")).to(StoreA.class);
    bind(Store.class).annotatedWith(Names.named("secondary")).to(StoreB.class);
    expose(A.class);
  }
});
install(new PrivateModule() {
  @Override public void configure() {
    bind(Store.class).annotatedWith(Names.named("primary")).to(StoreC.class);
    bind(Store.class).annotatedWith(Names.named("secondary")).to(StoreD.class);
    expose(B.class);
  }
});

因此,@Named("primary") StoreAB(或其依赖项)之外无法访问,但这是有道理的.您永远不会定义通用的Store,但是AB各自具有它们所需的专用绑定.

Consequently, @Named("primary") Store will not be accessible outside of A or B (or its dependencies), but that makes sense; you're never defining a general Store, but A and B each have the private bindings they need.

(免责声明:我没有机会进行测试,因此可能需要改进.)

(Disclaimer: I didn't get a chance to test this, so it may need refinement.)

这篇关于Guice-根据封闭的类绑定不同的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆