2014-02-19 38 views
2

我需要一個關於如何使用Google-guice爲服務編寫多個實現的建議。下面是示例使用Guice使用提供者的服務的多個實現

TestService testService =new TestServiceImplOne(); 
TestService testService =new TestServiceImplTwo(); 

作爲吉斯不允許類型結合到一個以上的實施方式中,如誤差下面的代碼結果

binderObject.bind(SomeType.class).to(ImplemenationOne.class); 
binderObject.bind(SomeType.class).to(ImplemenationTwo.class); 

我們可以與命名註解如下

解決這個
binder.bind(Player.class).annotatedWith(Names.named("Good")).to(GoodPlayer.class); 
binder.bind(Player.class).annotatedWith(Names.named("Bad")).to(BadPlayer.class); 

@Named("Good") Player goodPlayer = (Player)injector.getInstance(Player.class); 
@Named("Bad") Player badPlayer = (Player)injector.getInstance(Player.class); 

但我工作的應用程序是這樣的。我們結合在init()方法中的所有模塊和創建的注射器模塊:

//separate method to bind 
protected void configure() { 
    bind(new TypeLiteral<List<Service>>() {}).toInstance(serviceSets); 
} 

//separate method to inject 
Injector i = Guice.createInjector(modules); 

但上述過程中,我可以一個實現類只是綁定到接口(服務類)

你能請爲我提供一種與提供者一起完成此任務的方法。我想這樣做下面這樣

class TestServiceProvider extends Provider{ 
// some code where it returns the instance of impl class needed. In my case TestServiceImplOne and TestServiceImplTwo and provider returns the corresponding instance of service class 
} 

並綁定與提供者類的服務類。這樣

bind(TestService.class).toProvider(TestServiceProvider.class); 

的東西,如果有人建議使用提供商或者說我可以注入我想在客戶端執行的任何其他方式一個很好的例子,我將不勝感激。

注意:我正在使用webservices,我不確定如何在向服務類調用webservice時注入不同的實現。


First of all thanks very much for responding . Coming straight to the point 

Iam working on webservices . Heres's the Flow 

//獲取URI GET http://www.google.com:8182/indi/provide/organizations/ {}歐

OrganizationsResource -------->OrganizationService------>OrganizationServiceImpl 

Iam binding OrganizationService with OrganizationServiceImpl and injecting the OrganizationService in OrganizationsResource 

@Inject 
    public void setOrganizationService(OrganizationService orgService) { 
     this.orgService= orgService; 
    } 


Its fine till here but i have two implementations for OrganizationService ------>OrgDeatilsServiceImpl which does some other job 

Now i want to bind both OrganizationServiceImpl and OrgDeatilsServiceImpl to OrganizationService 

Confusions: 

1) What procedure i have to use in Guice to bind two implementaions? 
2) How exactly i can code in OrganizationsResource to dynamically decide which implementation to call. 


I would appreciate if you give a sample example for the above requirement. 
+2

這是絕對不清楚爲什麼你不能使用綁定註釋。請在這一部分展開。順便說一下你的註釋示例是錯誤的。註釋局部變量並用'Injector.getInstance()'調用賦值它們什麼都不會做。你必須使用'Key'類。 –

回答

4

正如普京指出,你可以使用綁定註釋與供應商...

// in YourModule.configure(): 
bind(TestService.class) 
    .annotatedWith(Names.named("foo") 
    .toProvider(TestServiceProvider.class); 

.. 。和泛型使用TypeLiterals ...

bind(new TypeLiteral<List<Service>>() {}) 
    .annotatedWith(Names.named("bar") 
    .toInstance(serviceSets); 

...只要你問使用getInstance(Key<T>)的註解實例...

List<Service> servicesOne = injector.getInstance(
    new Key<List<Service>>(Names.named("bar")) {}); 
// or 
List<Service> servicesTwo = injector.getInstance(
    Key.get(new TypeLiteral<List<Service>>() {}, Names.named("bar")); 

...或者,最好是將它作爲域,讓吉斯做注射,因爲可吉斯注入局部變量。請記住,Guice只能注入它創建的類,或者你需要專門請求。

class MyInjectorCreator { 
    @Inject @Named("foo") Provider<TestService> fooServiceProvider; 
    @Inject @Named("bar") List<Service> barServices; 
    // Guice will also wrap/unwrap Providers automatically. 
    @Inject @Named("foo") TestService fooService; 
    @Inject @Named("bar") Provider<List<Service>> barServicesProvider; 

    public void createInjector() { 
    Injector injector = Guice.createInjector(getListOfModules()); 
    injector.injectMembers(this); 
    } 
} 

現在,您可以在標題中回答問題了。這就是說,這聽起來像你真的想在運行時,這是一個略有不同,但容易解決問題的實現之間進行選擇:

class TestServiceProvider extends Provider<TestService> { 
    // Injection is allowed here! 
    @Inject ApplicationSettings settings; 
    @Inject Provider<TestServiceImplOne> oneProvider; 
    @Inject Provider<TestServiceImplTwo> twoProvider; 

    @Override public TestService get() { 
    if (settings.isInTestMode()) { 
     return new TestTestServiceImplImpl(); // without injection! 
    } else if (settings.useNewService()) { 
     return twoProvider.get(); // with injection! 
    } else { 
     return oneProvider.get(); // also with injection! 
    } 
    } 
} 

但我要提醒你,如果你知道在注入井創作你應該正確地綁定它,然後爲了代碼清潔和便於閱讀:

// in YourModule.configure(): 
if (settings.isInTestMode()) { 
    bind(TestService.class).toInstance(new TestTestServiceImplImpl()); 
} else if (settings.useNewService()) { 
    bind(TestService.class).to(TestServiceImplTwo.class); 
} else { 
    bind(TestService.class).to(TestServiceImplOne.class); 
} 
+0

在你的最後一個例子中,你將如何訪問「設置」? –