Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency injection with @Inject and Interface in Quarkus

I'm trying to resolve dependency injection with Repository Pattern using Quarkus 1.6.1.Final and OpenJDK 11. I want to achieve Inject with Interface and give them some argument(like @Named or @Qualifier ) for specify the concrete class, but currently I've got UnsatisfiedResolutionException and not sure how to fix it.

Here is the my portion of code.

UseCase class:

@ApplicationScoped
public class ProductStockCheckUseCase {
    @Inject
    @Named("dummy")
    ProductStockRepository repo;

    public int checkProductStock() {
        ProductStock stock = repo.findBy("");
        return stock.getCount();
    }
}

Repository Interface:

public interface ProductStockRepository {
    public ProductStock findBy(String productId);
}

Repository Implementation:

@Named("dummy")
public class ProductStockDummyRepository implements ProductStockRepository {

    public ProductStock findBy(final String productId) {
        final ProductStock productStock = new ProductStock();
        return productStock;
    }
}

And here is a portion of my build.gradle's dependencies:

dependencies {
    implementation 'io.quarkus:quarkus-resteasy'
    implementation 'io.quarkus:quarkus-arc'
    implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")

    testImplementation 'io.quarkus:quarkus-junit5'
    testImplementation 'io.rest-assured:rest-assured'
}

When I run this (e.g. ./gradlew assemble or ./gradlew quarkusDev ), I've got the following errors:

Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type ProductStockRepository and qualifiers [@Named(value = "dummy")]
        - java member: ProductStockCheckUseCase#repo
        - declared on CLASS bean [types=[ProductStockCheckUseCase, java.lang.Object], qualifiers=[@Default, @Any], target=ProductStockCheckUseCase]

Do you have any ideas how to fix this? or is it wrong idea to implement this kind of interface injection and specify the concrete class with argument/annotation?

I've read and tried the following articles:

Some official docs:

  • Quarkus - Contexts and Dependency Injection https://quarkus.io/guides/cdi-reference
  • JSR 365: Contexts and Dependency Injection for Java 2.0 https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#default_bean_discovery
  • Interfaces on Demand with CDI and EJB 3.1 https://www.oracle.com/technical-resources/articles/java/intondemand.html
  • 23.7 Injecting Beans - Java Platform, Enterprise Edition: The Java EE Tutorial (Release 7) https://docs.oracle.com/javaee/7/tutorial/cdi-basic007.htm

The other blogs and SOs:

  • java - how inject implementation of JpaRepository - Stack Overflow how inject implementation of JpaRepository
  • java - How to inject two instances of two different classes which implement the same interface? - Stack Overflow How to inject two instances of two different classes which implement the same interface?
  • Java EE Context and Dependency Injection @Qualifier https://memorynotfound.com/context-dependency-injection-qualifier/
like image 982
tkhm Avatar asked Aug 14 '20 12:08

tkhm


1 Answers

My guess is that you need to add a scope annotation to your ProductStockDummyRepository. Probably either @Singleton or @ApplicationScoped.

like image 65
Guillaume Smet Avatar answered Sep 30 '22 16:09

Guillaume Smet