Sunday, August 7, 2005

Inversion of Control in the ArcGIS Java ADF

Martin Fowler in a recent blog gave a good short explanation of the inversion of control pattern... In ESRI's ArcGIS Java ADF we employ this approach at a few places.

  1. The WebContextInitialize interface declares an init(WebContext) method. The ADF will call this method on objects which implement this interface and register themselves as attributes of the WebContext. This method will be called immediately after they are registered with the WebContext. Users interested in getting access to the associated WebContext object or want to do some initialization tasks should implement this interface.

  2. The WebLifecycle interface declares methods which will be called by the ADF at various phases of the webapp's lifecycle. Users can implement activation, passivation and destroy logic in these methods. This interface is most relevant when using pooled objects since users may want to rehydrate and dehydrate the states of the server objects when the ADF reconnects and releases its connection to the ArcGIS server on every request.

  3. The WebContextObserver interface declares an update(WebContext webContext, Object args) method. Objects implementing this interface can register themselves as observers of the WebContext by calling the addObserver(WebContextObserver) method. After users perform operations which change the state of the objects that they work with (for example zoom to a different extent, add a graphic element, etc.), they call the refresh() method on the WebContext. When this happens, the ADF iterates thru all the registered observers of the context and calls their update() methods. This ensures loose coupling among the various objects but at the same time gives these loosely coupled objects an opportunity to be in sync with the changed state of the app. This is a classic implementation of the observer pattern with the WebContext acting as the Observable object.

With the advent of JDK 5 annotations, it might be convenient for the users if #1 could be achieved by simply annotating a field or a setter method with an @Resource like annotation. The ADF on encountering this annotation on a WebContext field or setter method could inject the same into the interested object. Further, users can do the initialization tasks in any arbitrary method annotated with the @InjectionComplete annotation and the ADF will call this method immediately after injecting the WebContext. (Both these annotations are proposed by JSR 250 - Common Annotations).

#2 could also be achieved through annotations. Much like how EJB3 is proposing @PostActivate, @PrePassivate, et al; users can annotate the lifecycle methods with annotations such as @OnActivate, @OnPassivate and @OnDestroy. This would alleviate them of having to implement interfaces for lifecycle callbacks and further, they can choose to participate in only those phases of the ADF lifecycle which makes business sense for their objects.

Comments / feedbacks welcome.

No comments: