blob: 3d75dc6050e8eec20b4c0295aa4f8f3324c25b90 [file] [log] [blame]
= CDI Dynamic Inject
:index-group: CDI
:jbake-type: page
:jbake-status: published
== Introdução
As vezes precisamos escrever várias implementações para uma interface de regras de negócios, para aumentar o desacoplamento vamos injetar dinamicamente a implementação em tempo de execução.
== Exemplo 1
Neste exemplo, temos uma interface `Payment` e suas implementações:
- Cash
- CreditCard
Em nosso teste (`FinalizePaymentTest`) nós injetamos a classe FinalizePayment, e chamamos o método `finishWithCash`.
Esse método irá injetar dinamicamente a implementação correta usando os recursos do CDI
[source,java]
----
public String finishWithCash() {
paymentChoosed = paymentsLazy.select(Cash.class).get();
return paymentChoosed.pay();
}
----
observe que está sendo usado uma variável chamada de `paymentsLazy` essa variável irá conter todas as implementações da interface `Payment`
[source,java]
----
@Inject
@Any
private Instance<Payment> paymentsLazy;
----
Nessa variável estamos usando:
- Anotação `@inject`
Indica ao CDI que gostariamos de realizar um injeção de dependencia
- Anotação `@Any`
Indicar que deve ser listada todas as implementações possíveis.
- Objeto `Instance`
Objeto responsável por conhecer todas as implementações possíveis e instancia-las no momento desejado.
com essa variável pronta podemos chama-la usando o:
[source,java]
----
paymentsLazy.select(Cash.class).get();
----
onde `Cash.class` informa qual e a implementação e `.get()` retorna a instancia pronta para uso.
== Exemplo 2
Neste exemplo, temos uma interface `Payment` e suas implementações:
- Cash
- CreditCard
Em nosso teste (`FinalizePaymentQualifierTest`) nós injetamos a classe FinalizePayment, e chamamos o método `finishByQualifier`.
Esse método irá injetar dinamicamente a implementação correta usando um `Qualifier`(PaymentType).
[source,java]
----
public String finishByQualifier(PaymentType type) {
paymentChoosed = paymentsLazy.select( new PayByQualifier(type) ).get();
return paymentChoosed.pay();
}
----
Para essa abordagem funcionar precisaremos criar uma nova classe chamada `PayByQualifier` que extende `AnnotationLiteral` que espera a passagem de um qualifier em seu parametro `T extends Annotation`(Generics).
[source,java]
----
public class PayByQualifier extends AnnotationLiteral<PaymentQualifier> implements PaymentQualifier {
private PaymentType type;
public PayByQualifier(PaymentType type) {
this.type = type;
}
@Override
public PaymentType type() {
return this.type;
}
}
----
o importante e implementar o método da Anotação em nosso caso o `public PaymentType type();`
Para faciliar essa implementação recebemos esse valor por construtor de nossa nova classe
[source,java]
----
public PayByQualifier(PaymentType type) {
this.type = type;
}
----
Com essa classe pronta podemos usa-la em nossa classe de negócio:
[source,java]
----
paymentChoosed = paymentsLazy.select( new PayByQualifier(type) ).get();
----
Obs: A estrutura de qualifier foi reaproveitada do project https://github.com/cassunde/tomee/tree/master/examples/cdi-qualifier