2014-02-04 4 views
0

Возможно ли связать экземпляр Named на основе класса-оболочки? Например: в приведенном ниже примере классы A и B будут инсталлированы в экземпляр DataStore. Тем не менее, мне нужно иметь первичный магазин как StoreA и вторичный магазин StoreB в области/контексте класса A, но в качестве хранилища StoreC и вторичного хранилища как StoreD в области/контексте класса B. Как это можно достичь?Guice - связывать разные экземпляры на основе класса-окружения

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 

ответ

1

Это иногда называют "robot legs" problem, как будто строит робота с одинаковыми ногами, но различающиеся левой и правой ноги. Каждая нога связывает ногу, но запрашиваемая нога зависит от запрошенной ноги. В вашем случае каждый DataStore привязывается к основному и вторичному магазину, но какие магазины зависят от запрашиваемого DataStore.

Guice введенный экземпляр не может быть связан непосредственно на основе своей цели (а similar feature was rejected), но as mentioned in the FAQ вы можете использовать PrivateModule создать подобный эффект.

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") Store не будет доступен за пределами A или B (или его зависимости), но это имеет смысл; вы никогда не определяете общий Store, но A и B имеют свои собственные привязки, в которых они нуждаются.

(Отказ от ответственности: у меня не было возможности проверить это, поэтому может потребоваться уточнение.)

Смежные вопросы