OSGi Declarative Services is very attractive, which spares you from writing a lot of boiler plate code for things like registering/unregistering/consuming services.
I wanted to use OSGi's Declarative Services for dependency injection in RCP applications. For example, I had a view, in which I would like to use a service SimpleService advertised by Declarative services.
Problem
My first naive approach was to create a component.xml, in which the view class consumes SimpleService. Well, it did not work as I liked, because the view did not have SimpleService injected.
What went wrong?
Nothing went wrong. Declarative Services work as advertised, but my approach was way wrong.
To allow Declarative Services (DS) work, you have to ask DS to instantiate an object for you. During this process, DS injects all necessary services in this newly created object.
However, a view object was created by RCP application launcher outside DS. What I ended up with were a view object created by RCP application launcher, and another lonely view object created by DS with SimpleService injected but not used in my RCP application launcher.
What is a good approach to inject my SimpleService in my view object?
Solution (a solution)
In your RCP Application's Activator, use ServiceTracker to look up SimpleService. In your view, get SimpleService by Activator.getDefault().getSimpleService().
public class Activator extends AbstractUIPlugin {
public void start(BundleContext context) throws Exception {
super.start(context);
this.context = context;
lookupService(context);
plugin = this;
}
super.start(context);
this.context = context;
lookupService(context);
plugin = this;
}
public static Activator getDefault() {
return plugin;
}
return plugin;
}
private ServiceTracker tracker;
private ApplicationUserAdmin userAdmin;
private void initializeServiceLooup(BundleContext context) {
if(userAdmin!=null) {
return;
}
tracker = new ServiceTracker(context, SimpleService .class.getName(),null);
tracker.open();
}
public SimpleService getSimpleService() {
return (SimpleService ) tracker.getService();
}
private ApplicationUserAdmin userAdmin;
private void initializeServiceLooup(BundleContext context) {
if(userAdmin!=null) {
return;
}
tracker = new ServiceTracker(context, SimpleService .class.getName(),null);
tracker.open();
}
public SimpleService getSimpleService() {
return (SimpleService ) tracker.getService();
}
//other omitted here
}
No comments:
Post a Comment