We've also run into this problem but didn't want to use any 
technology/framework other than RCP, DS and OSGi. Our solution so far is rather 
a workaround, but works fine for us so far: 

We've created a generic service listener interface and a generic 
ServiceTracker: 

public interface IGenericServiceListener<S> {
        public void bindService(S service);
        public void unbindService(S service);
}

public class GenericServiceTracker<S> extends ServiceTracker {
        private S service;
        private List<IGenericServiceListener<S>> serviceListener;
        private final Class<S> clazz;

        public GenericServiceTracker(BundleContext context, Class<S> clazz) {
                super(context, clazz.getName(), null);
                this.clazz = clazz;
                this.serviceListener = Collections.synchronizedList(new 
ArrayList<IGenericServiceListener<S>>());
        }

        @Override
        public Object addingService(ServiceReference reference) {
                service = clazz.cast(super.addingService(reference));
                informListener();
                return service;
        }

        private void informListener() {
                for (IGenericServiceListener<S> listener : serviceListener) {
                        listener.bindService(service);
                }
        }

        public void addServiceListener(IGenericServiceListener<S> 
serviceListener) {
                // inform immediately if service available
                if (this.service != null) {
                        serviceListener.bindService(service);
                }
                this.serviceListener.add(serviceListener);
        }
}

The generic service interface and ServiceTracker are reusable. Next is the code 
you have always to write when interested in a specific service:

The activator in your RCP plug-in has to implement a specific 
addServiceListener method, e.g.
        public static void addFacilityServiceListener(
                        IGenericServiceListener<IFacilityService> listener) {
                this.facilityServiceTracker.addServiceListener(listener);
        }

And you have to start the ServiceTracker within the Activator-start() method:
                this.facilityServiceTracker = new 
GenericServiceTracker<IFacilityService>(context, IFacilityService.class);
                facilityServiceTracker.open();

Last thing to do is your RCP-ViewClass has to register a serviceListener e.g. 
within the constructor:

public MyRCPView() {
        MyActivator.addFacilityServiceListener(new 
IGenericServiceListener<IFacilityService>() {

                        @Override
                        public void bindService(IFacilityService service) {
                                // TODO Auto-generated method stub
                        }

                        @Override
                        public void unbindService(IFacilityService service) {
                                // TODO Auto-generated method stub
                        }               
                });
        }

Or you can implement the listener interface this way and have bindService() and 
unbindService() methods directly within your ViewClass

public class MyRCPView extends ViewPart implements 
IGenericServiceListener<IFacilityService>

Regards,
Eugen

Am 02.11.2010 um 13:34 schrieb O'Flynn, Dennis:

> Another dependency-injection approach is Spring.  Martin Libbert provided a 
> way to bridge extension points w/ spring beans.  See his blog at:
> * 
> http://martinlippert.blogspot.com/2008/05/dependency-injection-for-extensions.html
> 
> 
> -----Original Message-----
> From: [email protected] 
> [mailto:[email protected]] On Behalf Of Neil Bartlett
> Sent: Tuesday, November 02, 2010 7:11 AM
> To: Equinox development mailing list
> Subject: Re: [equinox-dev] Eclipse ViewPart and OSGI Declarative 
> Servicesproblem
> 
> Hi Richard,
> 
> This is a rather challenging area, because the lifecycles of services
> and extensions are completely unrelated. As you've noticed, creating a
> component with DS does not mean it will be used by the extension
> registry. Indeed it cannot be, because the extension registry is more
> like a factory where new instances are created each time they are
> needed.
> 
> I created a small framework to help with this kind of thing:
> http://github.com/njbartlett/extensions2services. Please be sure to
> read the manual (in PDF), because it helps to describe the background
> of the problem, even if you decide not to adopt my solution.
> 
> Other possible solutions, which all use or include a
> dependency-injection approach, are as follows:
> 
> 1) Eclipse Riena -- however Riena does a lot of other stuff that I
> don't really understand
> 2) Peaberry is based on Guice
> 3) Eclipse 4.0 ("e4") uses dependency injection everywhere, but this
> is not much use to you if you are using 3.x.
> 
> Regards,
> Neil
> 
> 
> On Mon, Nov 1, 2010 at 9:17 PM, Richard Catlin
> <[email protected]> wrote:
>> I have a ViewPart which depends on an OSGI Declarative Service.
>> 
>> I have it configured properly so that the service is injected into the
>> ViewPart via a bind method.  I can debug and see that this is working.
>> 
>> The problem I am having is that a new instance of the ViewPart is being
>> instantiated for viewing and that the instance that was injected is not
>> being used.
>> 
>> Any help is appreciated.
>> 
>> Thanks.
>> Richard Catlin
>> 
>> _______________________________________________
>> equinox-dev mailing list
>> [email protected]
>> https://dev.eclipse.org/mailman/listinfo/equinox-dev
>> 
>> 
> _______________________________________________
> equinox-dev mailing list
> [email protected]
> https://dev.eclipse.org/mailman/listinfo/equinox-dev
> _______________________________________________
> equinox-dev mailing list
> [email protected]
> https://dev.eclipse.org/mailman/listinfo/equinox-dev

_______________________________________________
equinox-dev mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/equinox-dev

Reply via email to