E4 @Named dependency injection and OSGi services [message #902056] |
Wed, 15 August 2012 16:49 |
Fabio Mancinelli Messages: 16 Registered: July 2009 |
Junior Member |
|
|
Hi everybody,
I am trying to do the following without luck: I am writing a bunch of
OSGi plugins that will provide services that will be used in an E4
application.
I have an interface IStorage that is implemented by different plugins,
each one providing a particular type of storage (e.g., local, remote, etc.)
Now, I would like to be able to choose the particular "type" using
@Named annotations, something like
@Inject
@Named("remote")
IStorage remoteStorage
The problem is that I cannot make it work.
In my pure OSGi plugin I've tried the following:
1) Creating a declarative service that provides the IStorage interface
and whose name is "remote".
2) Getting an Eclipse context in my plugin's activator using
EclipseContextFactory. getServiceContext(bundleContext); and putting the
"remote" implementation in it using context.set("remote", new
RemoteStorage())
They both don't work.
So the question is: is it possible, in a pure OSGi world, to use E4 DI
to provide different services implementing a given interface and
selecting them using the @Named annotation?
Thanks,
Fabio
P.S.: Registering a service using bundleContext.register(IStorage.class,
new RemoteStorage(), null) works perfectly when I try to @Inject
IStorage somewhere. The problem is that in this way I cannot select one
implementation when multiple ones are available.
|
|
|
Re: E4 @Named dependency injection and OSGi services [message #902143 is a reply to message #902056] |
Thu, 16 August 2012 06:30 |
Thomas Schindl Messages: 6651 Registered: July 2009 |
Senior Member |
|
|
No - e4 DI will always pick the first one it finds. The @Named
annotation will simply make the DI container search for a key "remote"
instead of "IStorage.class.getName()"
You could invent you own annotation which searches the OSGi-Service
registry differently.
So you'd write:
@Inject
@OSGiNamed("remote")
IStorage remoteStorage
Tom
Am 15.08.12 18:49, schrieb Fabio Mancinelli:
> Hi everybody,
>
> I am trying to do the following without luck: I am writing a bunch of
> OSGi plugins that will provide services that will be used in an E4
> application.
>
> I have an interface IStorage that is implemented by different plugins,
> each one providing a particular type of storage (e.g., local, remote, etc.)
>
> Now, I would like to be able to choose the particular "type" using
> @Named annotations, something like
>
> @Inject
> @Named("remote")
> IStorage remoteStorage
>
> The problem is that I cannot make it work.
>
> In my pure OSGi plugin I've tried the following:
>
> 1) Creating a declarative service that provides the IStorage interface
> and whose name is "remote".
>
> 2) Getting an Eclipse context in my plugin's activator using
> EclipseContextFactory. getServiceContext(bundleContext); and putting the
> "remote" implementation in it using context.set("remote", new
> RemoteStorage())
>
> They both don't work.
>
> So the question is: is it possible, in a pure OSGi world, to use E4 DI
> to provide different services implementing a given interface and
> selecting them using the @Named annotation?
>
> Thanks,
> Fabio
>
> P.S.: Registering a service using bundleContext.register(IStorage.class,
> new RemoteStorage(), null) works perfectly when I try to @Inject
> IStorage somewhere. The problem is that in this way I cannot select one
> implementation when multiple ones are available.
|
|
|
|
Re: E4 @Named dependency injection and OSGi services [message #902249 is a reply to message #902143] |
Thu, 16 August 2012 14:11 |
Fabio Mancinelli Messages: 16 Registered: July 2009 |
Junior Member |
|
|
On 08/16/2012 08:30 AM, Tom Schindl wrote:
> No - e4 DI will always pick the first one it finds. The @Named
> annotation will simply make the DI container search for a key "remote"
> instead of "IStorage.class.getName()"
>
Thanks Tom for your reply.
What you said was clear to me. It was just the I thought that the @Named
annotation, somehow, affected also the way the OSGi services were searched.
As Lars suggested maybe a feature request here makes sense because
since OSGi declarative services have a provided interface and also a
name, this perfectly fits the use case
@Inject @Named("component-name") ProvidedInterface service;
Thanks,
Fabio
> You could invent you own annotation which searches the OSGi-Service
> registry differently.
>
> So you'd write:
>
> @Inject
> @OSGiNamed("remote")
> IStorage remoteStorage
>
> Tom
>
> Am 15.08.12 18:49, schrieb Fabio Mancinelli:
>> Hi everybody,
>>
>> I am trying to do the following without luck: I am writing a bunch of
>> OSGi plugins that will provide services that will be used in an E4
>> application.
>>
>> I have an interface IStorage that is implemented by different plugins,
>> each one providing a particular type of storage (e.g., local, remote, etc.)
>>
>> Now, I would like to be able to choose the particular "type" using
>> @Named annotations, something like
>>
>> @Inject
>> @Named("remote")
>> IStorage remoteStorage
>>
>> The problem is that I cannot make it work.
>>
>> In my pure OSGi plugin I've tried the following:
>>
>> 1) Creating a declarative service that provides the IStorage interface
>> and whose name is "remote".
>>
>> 2) Getting an Eclipse context in my plugin's activator using
>> EclipseContextFactory. getServiceContext(bundleContext); and putting the
>> "remote" implementation in it using context.set("remote", new
>> RemoteStorage())
>>
>> They both don't work.
>>
>> So the question is: is it possible, in a pure OSGi world, to use E4 DI
>> to provide different services implementing a given interface and
>> selecting them using the @Named annotation?
>>
>> Thanks,
>> Fabio
>>
>> P.S.: Registering a service using bundleContext.register(IStorage.class,
>> new RemoteStorage(), null) works perfectly when I try to @Inject
>> IStorage somewhere. The problem is that in this way I cannot select one
>> implementation when multiple ones are available.
>
|
|
|
Re: E4 @Named dependency injection and OSGi services [message #902344 is a reply to message #902249] |
Fri, 17 August 2012 08:31 |
Eclipse User |
|
|
|
Well the @Inject in e4 is meant primarily to inject dependencies which basically means decouple the interface from the implementation. While I agree there may be cases that direct implementation reference from the client of the injection is appropriate (OSGi services maybe one of them) , in general I think it should not be encouraged by the framework as DI is the highest level of implementation-hiding patterns.
The @Named does influence the way services are searched but searches for a specific named interface (service) in the context, not a specific implementation for a given interface.
Maybe one solution would be to plug in a context function and let it pick the implementation based on the context. If you are in a "remote" context the CF can select the remote variant of IService, if you are in a "local" context it should select the local one. But your client code would be just @Inject IService and the logic of the implementation switching would be a small and easy extension to the framework.
Maybe I ranted too much but I hope this helps.
|
|
|
|
Re: E4 @Named dependency injection and OSGi services [message #902803 is a reply to message #902228] |
Mon, 20 August 2012 14:01 |
|
+1
If we know the service is in the OSGi context then it would avoid the unnecessary search up the tree (cleaner and more efficient). I might modify it to something like:
@OSGiNamed(name="someName", tag="someTags")
This way it would be possible to differentiate multiple providers.
JD
|
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.04542 seconds