guice - the value of binding annotations -
the typical example of using binding annotation :-
public class realbillingservice implements billingservice { @inject public realbillingservice(@paypal creditcardprocessor processor, transactionlog transactionlog) { ... }
i'd understand value of annotation, 'cause can't create constructor binding
public class realbillingservice implements billingservice { @inject public realbillingservice(@bankabc creditcardprocessor processor, transactionlog transactionlog) { ... }
it looks superfluous in defining example, must missing something.
i
public class bankbillingservice implements billingservice { @inject public bankbillingservice(@bank creditcardprocessor processor, transactionlog transactionlog) { ... }
but i'd still have bind both (or more) classes
bind(creditcardprocessor.class) .annotatedwith(paypal.class) .to(paypalcreditcardprocessor.class); bind(creditcardprocessor.class) .annotatedwith(bank.class) .to(bankcreditcardprocessor.class);
and have bunch of if that, kind of negating value (by understanding) of guice.
the goal binding annotations distinguish 2 different injection keys same class or type. in quoted example:
public class realbillingservice implements billingservice { @inject public realbillingservice(@paypal creditcardprocessor processor, transactionlog transactionlog) { ... }
you might provide alternative implementation:
public class stripebillingservice implements billingservice { @inject public realbillingservice(@stripe creditcardprocessor processor, transactionlog transactionlog) { ... }
or operate @ higher degree of abstraction:
public class realbillingservice implements billingservice { @inject public realbillingservice(@international creditcardprocessor processor, transactionlog transactionlog) { ... }
one inject multiple arguments of similar types:
@inject public realorderrepository( @customer datastore customerdatastore, @order datastore orderdatastore, @item datastore itemdatastore) { /* ... */ }
as alternative this, creates multiple unnecessary types in hierarchy , makes harder or impossible create , replace generic implementations:
// ideally should have implementations inmemorydatastore , awsdatastore; // below force inmemorycustomerdatastore or localdbitemdatastore // regardless of whether need them or not. public interface customerdatastore extends datastore { /* empty */ } public interface orderdatastore extends datastore { /* empty */ } public interface itemdatastore extends datastore { /* empty */ } @inject public realorderrepository( customerdatastore customerdatastore, orderdatastore orderdatastore, itemdatastore itemdatastore) { /* ... */ }
ultimately, use of binding annotations should pretty rare, distinguish different injection requests otherwise same type. in example, if wouldn't need @bank creditcardprocessor
, @paypal creditcardprocessor
@ same time in same application, bind creditcardprocessor
once , done it. however, if might coexist, bind them same credit card processor, or different card processors, or may need change.
see also: guice's bindingannotations docs , jsr-330's @qualifier annotation docs
Comments
Post a Comment