Sunday, April 3, 2011

Immutable Instance Variables with Method Injection in Guice

In my previous post I showed one of the downsides to method injection in Guice, which is you can't make the fields that are set via those methods immutable by marking them final. This is a shame because method injection can be very handy, and given it is also inherited by classes extending your class, it is useful in abstract classes up the hierarchy. One way around this is using an ImmutableHolder class. The class would look something like this and impose simple write-once, read only after initialization semantics:

Our configurable class would be slightly more complicated, as the setter/getter for this data would have to get or set the underlying data from our Holder (very similar to how you might wrap some data with a SoftReference or WeakReference):

But it's use is now transparent to the outside users of this class. Unfortunately, we still have the ability to create our ConfigurableClass without initializing it since we're using an optionally injected setter, though you don't have to do this. However, instead of getting a null value back and eventually throwing a NullPointerException when we try to use the Configuration object (which could be in a completely different context if we pass it along to other functions) we will get an UnitializedException as early as possible. This technique could very well be a viable tradeoff in the cases where we want to fail earlier and with a more obvious message, as well as offer write-once semantics while using method injection.

Disclaimer: The above code is intended to be illustrative and was not thoroughly tested.

No comments:

Post a Comment