Philosophy of Guice

Dependencies injection + interfaces

Classes are glued together by interfaces, and implemented classes are injected in run-time.
---Compile time: interface calls interface, run time: implementation calls implementation. In between taken care by Guice.
  • we don't need implemented classes to get compiled.
  • we could change to different implemented classes on the fly.
  • No need to rewrite test client.
Guice
  • What to inject: map interface to real implementation, this is the place we'll make the change. Keep mind, bind interface to implementation is the best practice, but you could also bind any class to its sub class, as long as they are the same type or implements the same interface.
public class BillingModule extends AbstractModule
{
  @Override 
  protected void configure()
  {
    bind(TransactionLog.class).to(DatabaseTransactionLog.class);
    bind(CreditCardProcessor.class).to(PaypalCreditCardProcessor.class);
    bind(BillingService.class).to(RealBillingService.class);
  }
}
  • Where to inject: mark the location to tell Guice where to replace interface with implementation
public class RealBillingService implements BillingService 
{
  private final CreditCardProcessor processor;
  private final TransactionLog transactionLog;

  @Inject
  public RealBillingService(CreditCardProcessor processor, TransactionLog transactionLog) 
  {
    this.processor = processor;
    this.transactionLog = transactionLog;
  }
....
}
  • How to inject: Usage of Guice, create injector based on module, injector is like a map.
public static void main(String[] args) 
{
    Injector injector = Guice.createInjector(new BillingModule());
    BillingService billingService = injector.getInstance(BillingService.class);
    ...
}

Invoke Method

ResultSet rs....
int index ...

Object obj = rs.getObject(index);
obj = rs.getTimestamp(index);
//this will throws exception "oracle.sql.TIMESTAMP cannot be cast to java.sql.Timestamp"

To solve this problem:


Class clz = obj.getClass();
Method method = clz.getMethod("timestampValue", null);
obj = (Timestamp) method.invoke(obj, null);

Flex Object

setter:
var obj:Object = new Object();
obj.name="test";

getter:
var name:String = obj[name];

Why can't we just call obj.name to get the value? You could only if you could directly use the property name onto the object. You could not do like the following:

var key:String = "name";
var nameValue=obj.key; //this will not work
var nameValue2=obj.name; //this will work

The only way you could do is through []

var nameValue3=obj[key]; //this will work, and recommended

We could actually take property_name == ["property_name"].

Conversion between Java object and Flex object:

Objects are serialized using Java bean introspection rules and also include public fields. Fields that are static, transient, or nonpublic, as well as bean properties that are nonpublic or static, are excluded.

So only public-non-static fields will be transferred to Flex object.