cheparsky
cheparsky

Reputation: 530

How can I get Singletons from @Provides method?

I have Module with @Provides method:

class EnvironmentModule extends AbstractModule {

    static String CURRENT_PRODUCT

    @Override
    protected final void configure() {
    }

        @Provides
    static ProcessBuilder get(){
        return CURRENT_PRODUCT == 'Product1' ? new Product1ProcessBuilder() : new Product2ProcessBuilder()
    }

Class where I Inject ProcessBuilder:

class Operation {

    @Inject
    Provider<ProcessBuilder> processBuilder

    void operate() {
        def process = processBuilder.get().build()
    }
}

Step how I execute my test:

  1. CURRENT_PRODUCT = 'Product1'
  2. operate() give us instance of prodcut1, e.g Product1ProcessBuilder@26aecf31
  3. CURRENT_PRODUCT = 'Product2'
  4. operate() give us instance of prodcut2, e.g Product2ProcessBuilder@4bb4adf7
  5. CURRENT_PRODUCT = 'Product1'
  6. operate() give us instance of prodcut1, e.g Product1ProcessBuilder@11544ddd
  7. CURRENT_PRODUCT = 'Product2'
  8. operate() give us instance of prodcut2, e.g Product2ProcessBuilder@38e46ea

How can I get the same instance in steps 2), 6) and 4), 8) ?

When I annotate @Provides method with @Singleton it always returns the same instance of the first returned product. When I annotate each class products class with @Singleton then I have each time another product.

Upvotes: 2

Views: 304

Answers (2)

SQA
SQA

Reputation: 68

In EnvironmentModule class your get() method should be:

 @Provides
    static ProcessBuilder get(Product1ProcessBuilder product1CommonBorrowOperations, Product2ProcessBuilder product2CommonBorrowOperations) {
        return CURRENT_PRODUCT == 'Product1' ? product1CommonBorrowOperations : product2CommonBorrowOperations
    }

Your classes Product1ProcessBuilder and Product2ProcessBuilder also should be annotated with @Singleton to get same instance in steps 2), 6) and 4), 8)

Upvotes: 1

Olivier Gr&#233;goire
Olivier Gr&#233;goire

Reputation: 35457

You can do what you want with just a tad more configuration:

@Provides @Singleton @Named("Product1")
static ProcessBuilder provideProduct1ProcessBuilder() {
  return new Product1ProcessBuilder();
}

@Provides @Singleton @Named("Product2")
static ProcessBuilder provideProduct2ProcessBuilder() {
  return new Product2ProcessBuilder();
}

static String CURRENT_PRODUCT;

@Provides static ProcessBuilder get(
    @Named("Product1") ProcessBuilder product1ProcessBuilder,
    @Named("Product2") ProcessBuilder product2ProcessBuilder) {
  // Note the absence of @Singleton
  return "Product1".equals(CURRENT_PRODUCT) ? product1ProcessBuilder : product2ProcessBuilder;
}

Upvotes: 0

Related Questions