2014-02-19 43 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

在你的最后一个例子中,你将如何访问“设置”? –