Services und Dependency Injection in der Eclipse 4.0 Application Platform

Seite 2: Fazit

Inhaltsverzeichnis

Der in e4 eingeführte DI-Mechanismus erlaubt es, Code kompakt zu gestalten, da das Framework eine Menge Arbeit abnimmt. Um etwa in Eclipse 3.6 die aktuelle Selektion der Workbench abzurufen, sind folgende Zeilen unumgänglich:

public class MyView extends ViewPart {
  public void createPartControl(Composite parent) {
getSite().getSelectionProvider().addSelectionChangedListener(
new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
if (event.getSelection() instanceof IStructuredSelection) {
Object o = ((IStructuredSelection) event
.getSelection()).getFirstElement();
if (o instanceof YourObject) {
foo((YourObject) o);
}
}
}
});
}
  void foo(YourObject o) { /* auf Selektion reagieren */ }
}

Im Eclipse 4.0 SDK lässt sich die aktuelle Selektion über DI wie folgt abrufen:

public class MyPart {
    @Inject  // initialisiere den Parameter YourObject o via DI
void foo(@Named(IServiceConstants.ACTIVE_SELECTION) YourObject o) {
// auf Selektion reagieren
}
}

Hier trumpft das DI-Framework auf, da es die richtige Selektion typsicher an die foo-Methode übergibt. Vergleicht man beide Codeabschnitte, zeigt sich, dass der e4-Ansatz kompakter und eingängiger ist. Häufig anfallende Aufgaben wie Typprüfungen oder die Registrierung von Listenern übernimmt das Framework.

Nach Meinung der Autoren zeichnet genau das ein gutes Framework aus: knapper, aber aussagekräftiger Code gepaart mit effizienten Automatismen, die dem Entwickler wiederkehrende Tätigkeiten abnehmen.

Das Workbench-Modell gestattet außerdem die Definition eigener Variablen, die sich im IEclipseContext setzen lässt. Folgende Abbildung zeigt, dass im Window-Kontext eine Variable "selection" definiert wird. Die Variable kann man jetzt in einem Modellelement auslesen oder neu setzen. Das folgende Beispiel zeigt, wie sich über den injizierten IEclipseContext die Variable "selection" neu setzen lässt.

public class MyPart {

      @Inject
public void setSelection(IEclipseContext context) {
if (context != null) {
context.modify("selection", new MySelection());
}
}
}

Ein anderes Modellelement kann nunmehr auf die Variable via DI zugreifen, wie das anschließende Beispiel zeigt. Hier initialisiert DI den Methodenparameter mySelection, und die printMySelection-Methode gibt das Ergebnis aus. Die @Named-Annotation spezifiziert den Namen der Variablen, wobei das DI-Framework für die Auflösung der Referenz zuständig ist.

@Inject
void printMySelection(@Named("selection") MySelection mySelection){
System.out.println(mySelection.toString());
}

Eclipse 4 stellt einige Standard-Services zur Verfügung, auf die sich, wie gezeigt, via DI zugreifen lässt. Anfänglich hatten die an Eclipse 4 Beteiligten die Standard-Services als "The 20 Things" bezeichnet, um zu verdeutlichen, dass man sich auf wenige essenzielle Services konzentrieren möchte. Auch wenn es nicht genau 20 Services geworden sind, wird an der Idee festgehalten, die Anzahl überschaubar zu gestalten. Die Workbench-Services folgen zumeist dem E*Service-Muster.

Workbench-Services:

  • org.eclipse.e4.core.commands.ECommandService
  • org.eclipse.e4.core.commands.EHandlerService
  • org.eclipse.e4.workbench.modeling.EPartService
  • org.eclipse.e4.workbench.modeling.EModelService
  • org.eclipse.e4.workbench.modeling.ESelectionService
  • org.eclipse.e4.ui.bindings.EBindingService
  • org.eclipse.e4.ui.services.EContextService

Weitere Standard-Services:

  • org.eclipse.e4.core.services.Adapter
  • org.eclipse.e4.core.services.StatusReporter
  • org.eclipse.e4.core.services.Logger
  • org.eclipse.e4.core.services.events.IEventBroker
  • org.eclipse.e4.workbench.ui.IPresentationEngine
  • org.eclipse.jface.window.IShellProvider

Eclipse 4.0 erlaubt es, Code kurz und knapp zu halten. Viel Code, der früher notwendig war, lässt sich durch das neue Programmiermodell vermeiden. DI ermöglicht es, Abhängigkeiten von Modellelementen lose zu definieren, was die Wiederverwendung und das Testen der Komponenten erheblich erleichtert.

Die lose Koppelung hat jedoch auch Nachteile. Die Verwaltung der Abhängigkeiten durch DI-Container erschwert es dem Entwickler, sich die tatsächlichen Abhängigkeiten zu verdeutlichen, Implementierungsklassen aufzufinden oder Code-Completion in Eclipse zu nutzen. Aber wenn die Eclipse-Entwickler erst einmal anfangen, ihr eigenes Hundefutter zu essen ("Eat your own dog food!"), wird sich die Tool-Unterstützung für DI in absehbarer Zeit verbessern.

Da DI die Welt der Web-Frameworks im Sturm erobert hat, bleibt zu hoffen, dass sich das Modell auch für die Desktop-Applikationsentwicklung durchsetzt. Für die RCP- und Plug-in-Entwicklung mit Eclipse wäre es eine echte Bereicherung, und die Implementierung an sich würde zukünftig noch schneller von der Hand gehen.

Lars Vogel
ist freiberuflich im Java-/Eclipse-Umfeld als Trainer und Entwickler tätig und zusätzlich als Produkt-Manager bei der SAP AG angestellt. Unter seiner Website veröffentlicht er Tutorials über Java, Eclipse, Android und zur Webentwicklung (Twitter: @vogella).

Matthias Heinrich
ist im SAP Research Center Dresden angestellt und beschäftigt sich mit aktuellen Techniken im Bereich der modellgetriebenen Softwareentwicklung.

Beide Autoren danken Boris Bokowski und Tom Schindl, die das Schreiben des Artikels überhaupt erst ermöglichten.

(ane)