3636package org .scijava .service ;
3737
3838import org .scijava .Context ;
39+ import org .scijava .event .EventService ;
3940import org .scijava .plugin .SortablePlugin ;
4041
4142/**
@@ -48,10 +49,17 @@ public abstract class AbstractService extends SortablePlugin implements
4849{
4950
5051 /**
51- * A pointer to the service's {@link Context}. Note that the context is not
52- * set in the superclass until {@link #initialize()} is called; this deferral
53- * ensures that event handler methods are not registered until after service
54- * initialization is complete.
52+ * A pointer to the service's {@link Context}. Note that for two reasons, the
53+ * context is not set in the superclass:
54+ * <ol>
55+ * <li>As services are initialized, their dependencies are recursively created
56+ * and initialized too, which is something that normal context injection does
57+ * not handle. I.e., the {@link Context#inject(Object)} method assumes the
58+ * context and its associated services have all been initialized already.</li>
59+ * <li>Event handler methods must not be registered until after service
60+ * initialization is complete (i.e., during {@link #registerEventHandlers()},
61+ * after {@link #initialize()}).</li>
62+ * </ol>
5563 */
5664 private Context context ;
5765
@@ -64,9 +72,12 @@ public void initialize() {
6472
6573 @ Override
6674 public void registerEventHandlers () {
67- // NB: The AbstractContextual superclass automatically takes
68- // care of registering event handlers when its context is set.
69- super .setContext (context );
75+ // TODO: Consider removing this method in scijava-common 3.0.0.
76+ // Instead, the ServiceHelper could just invoke the lines below directly,
77+ // and there would be one less boilerplate Service method to implement.
78+ final EventService eventService =
79+ getContext ().getService (EventService .class );
80+ if (eventService != null ) eventService .subscribe (this );
7081 }
7182
7283 // -- Contextual methods --
@@ -78,8 +89,10 @@ public Context getContext() {
7889
7990 @ Override
8091 public void setContext (final Context context ) {
81- // NB: Do not call super.setContext(Context) yet!
82- // It happens later, in registerEventHandlers().
92+ // NB: Do not call super.setContext(Context)!
93+ // The ServiceHelper populates service parameters.
94+ // We do this because we need to recursively create and initialize
95+ // service dependencies, rather than merely injecting existing ones.
8396 this .context = context ;
8497 }
8598
0 commit comments