I got the bindings wrong, correcting that.  Also illustrating how the
superclass of Providers gets common dependencies.

public class MyModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(ExecutorService.class)
            .annotatedWith(Names.named("single"))
            .toProvider(SingleProvider.class);

        bind(ExecutorService.class)
            .annotatedWith(Names.named("pool"))
            .toProvider(PoolProvider.class);
    }
}

class SomeDependency {}
class AnotherDependency {}
class CommonDependency1 {}
class CommonDependency2 {}
class CommonDependency3 {}

abstract class GenericExecutorProvider implements Provider<ExecutorService>
{

    @Inject
    GenericExecutorProvider(final CommonDependency1 d1,
                            final CommonDependency2 d2,
                            final CommonDependency3 d3) {}

    public abstract ExecutorService get();
}

class SingleProvider extends GenericExecutorProvider {

    @Inject
    SingleProvider(final SomeDependency d,
                   final CommonDependency1 d1,
                   final CommonDependency2 d2,
                   final CommonDependency3 d3) {
        super(d1,d2,d3);
    }

    public ExecutorService get() {
        // construct and return an ExecutorService
        // based on SomeDependency
        return null;
    }
}

class PoolProvider extends GenericExecutorProvider {

    @Inject
    PoolProvider(final AnotherDependency d,
                 final CommonDependency1 d1,
                 final CommonDependency2 d2,
                 final CommonDependency3 d3) {
        super(d1,d2,d3);
    }

    public ExecutorService get() {
        // construct and return an ExecutorService
        // based on AnotherDependency
        return null;
    }
}


On Wed, Mar 9, 2011 at 10:18 AM, Russ Milliken <[email protected]>wrote:

> I would do the "class" solution in a more OO way (eliminate the "switch"):
>
> public class MyModule extends AbstractModule {
>
>     @Override
>     protected void configure() {
>         bind(GenericExecutorProvider.class)
>             .annotatedWith(Names.named("single"))
>             .to(SingleProvider.class);
>
>         bind(GenericExecutorProvider.class)
>             .annotatedWith(Names.named("pool"))
>             .to(PoolProvider.class);
>     }
> }
>
> abstract class GenericExecutorProvider implements Provider<ExecutorService>
> {
>     public abstract ExecutorService get();
> }
>
> class SingleProvider extends GenericExecutorProvider {
>
>     @Inject
>     SingleProvider(final SomeDependency d) { }
>
>     public ExecutorService get() {
>         // construct and return an ExecutorService
>         // based on SomeDependency
>         return null;
>     }
> }
>
> class PoolProvider extends GenericExecutorProvider {
>
>     @Inject
>     PoolProvider(final AnotherDependency d) { }
>
>     public ExecutorService get() {
>         // construct and return an ExecutorService
>         // based on AnotherDependency
>         return null;
>     }
> }
>
>
> 2011/3/9 Sam Berlin <[email protected]>
>
> You can have one provider for both bindings, but the provider can't
>> disambiguate based on what it's providing (that is, there's know of knowing
>> the thing it's providing for).
>>
>> You could do this with less code with @Provides methods (or also simulate
>> it if you're stuck with classes).  For example:
>>
>> @Provides @Named("single") ExecutorService provideSingle(AnotherDependency
>> ad) {
>>    return makeExecutor(ad, Type.SINGLE);
>>  }
>>
>> @Provides @Named("pool") ExecutorService  providePool(AnotherDependency
>> ad) {
>>    return makeExecutor(ad, Type.POOL);
>> }
>>
>> private ExecutorService  makeExecutor(AnotherDependency ad, Type type) {
>> ...  }
>>
>> ---  or, using classes ---
>>
>> class SingleProvider extends GenericExecutorProvider {
>>   SingleProvider() {    super(Type.SINGLE);    }
>>  }
>>
>> class PoolProvider extends GenericExecutorProvider {
>>   PoolProvider() {   super(Type.POOL);  }
>>  }
>>
>> class GenericExecutorProvider implmenets Provider<ExecutorService> {
>>    final Type type;
>>    GenericExecutorProvider(Type type) { this.type = type; }
>>
>>    @Inject injectDependency(AnotherDependency ad) { .... }
>>
>>    ExecutorService get() {
>>       switch(type) { ... }
>>    }
>>  }
>>
>>
>> sam
>>
>> 2011/3/9 Bahri Gençsoy <[email protected]>
>>
>>
>>> Hi, I am trying to achieve some binding with Guice 2.0. I did search the
>>> mailing list but couldn't find a similar problem/solution.
>>>
>>> I am trying to bind different implementations of same interface. I want
>>> to discriminate them against their annotations.
>>>
>>> These are my classes to be injected dependencies to, I do not want to
>>> change them a lot:
>>>
>>> class SingleRunner {
>>>     @Inject
>>>     public void setExecutor(@Named("single") ExecutorService executor) {
>>>         // ...
>>>     }
>>> }
>>>
>>> class PoolRunner {
>>>     @Inject
>>>     public void setExecutor(@Named("pool") ExecutorService executor) {
>>>         // ...
>>>     }
>>> }
>>>
>>> This is the traditional approach to bind providers for these classes;
>>> creating to provider classes and bind them:
>>>
>>> class SingleProvider implements Provider<ExecutorService> {
>>>     @Inject
>>>     private SomeOtherDependency other;
>>>
>>>     public ExecutorService get() {
>>>         return singleExecutorService;
>>>     }
>>>
>>> }
>>>
>>> class PoolProvider implements Provider<ExecutorService> {
>>>     @Inject
>>>     private SomeOtherDependency other;
>>>
>>>     public ExecutorService get() {
>>>         return poolExecutorService;
>>>     }
>>>
>>> }
>>>
>>> class MyModule extends AbstractModule {
>>>     @Override
>>>     protected void configure() {
>>>
>>> bind(ExecutorService.class).annotatedWith(Names.named("pool")).toProvider(PoolProvider.class);
>>>
>>> bind(ExecutorService.class).annotatedWith(Names.named("single")).toProvider(SingleProvider.class);
>>>     }
>>> }
>>>
>>> But I am not comfortable with creating two provider classes. I want one
>>> provider class to provide all instances, ie something like that:
>>>
>>> class AllExecutorProvider {
>>>     @Inject
>>>     public void setSomeOtherDependency(SomeOtherdependency dep) {
>>>         // ...
>>>     }
>>>
>>>     public ExecutorService getExecutor(String name) {
>>>         if (name.equals("pool")) {
>>>             return poolExecutor;
>>>         } else if (name.equals("single")) {
>>>             return singleExecutor;
>>>         } else {
>>>             return null;
>>>         }
>>>     }
>>> }
>>>
>>>
>>> Thanks in advance
>>>
>>>
>>>  --
>>> You received this message because you are subscribed to the Google Groups
>>> "google-guice" group.
>>> To post to this group, send email to [email protected].
>>> To unsubscribe from this group, send email to
>>> [email protected].
>>> For more options, visit this group at
>>> http://groups.google.com/group/google-guice?hl=en.
>>>
>>
>>  --
>> You received this message because you are subscribed to the Google Groups
>> "google-guice" group.
>> To post to this group, send email to [email protected].
>> To unsubscribe from this group, send email to
>> [email protected].
>> For more options, visit this group at
>> http://groups.google.com/group/google-guice?hl=en.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"google-guice" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-guice?hl=en.

Reply via email to