You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by "Jan J. Roman" <po...@jjroman.net> on 2015/03/11 22:46:26 UTC

Dependency Manger - multiple instances of service

Hello,

I am exploring possibility of using felix and osgi in general for
developing home automation project on raspberry pi.

I created PinService of which one instance reflects one physical pin on
RPI. Instances are identified by property value. Now I am building service
which relay on two pins so I need two instances of PinServiceImpl in one
activator.

I am using Felix Dependency Manager to simplify dependencies and to inject
services. Below is a code that I am working with however it is not ideal as
it uses two different classes to inject one service to each class. I would
like to have two instances injected into one class.

Is there out of the box way to achieve this?
Is there better way to manage dependencies in osgi & felix?

in Activator:

 public void init(BundleContext bundleContext, DependencyManager
dependencyManager) throws Exception {
        {
dependencyManager.add(createComponent()
                            .setInterface(Object.class.getName(), null)
                            .setImplementation(PinConsumerFan.class)
                            .add(createServiceDependency()
                                    .setService(IGPIOPin.class,
"(PinNumber=1)")
                                    .setRequired(true))

.add(createServiceDependency().setService(LogService.class))
            );
dependencyManager.add(createComponent()
                            .setInterface(Object.class.getName(), null)
                            .setImplementation(PinConsumerDispenser.class)
                            .add(createServiceDependency()
                                    .setService(IGPIOPin.class,
"(PinNumber=2)")
                                    .setRequired(true))

.add(createServiceDependency().setService(LogService.class))
            );
}

Thanks in advance for any hints.

Regards
Jan Roman

Re: Dependency Manger - multiple instances of service

Posted by "Jan J. Roman" <ma...@jjroman.net>.
Thanks guys,
This is exactly what I was looking for. It works like a charm ;-) .

Regards
Jan

On 12 March 2015 at 09:16, Marcel Offermans <ma...@luminis.nl>
wrote:

> Hello Angelo, Jan,
>
> In general, Angelo is completely right, but there is one thing in his
> response that is not:
>
> .setService(IGPIOPin.class, "&((" + Constants.OBJECTCLASS + "=" +
> IGPIOPin.class.getName() + ")(PinNumber=1))")
> .setRequired(true)
> .setAutoConfig("fanPin"))
> In the code above, Angelo added the ObjectClass to the filter, because:
>
> Remember to include the ObjectClass in the filter, as you override the
> service filter that would normally be created, and you could end up with
> any other service that has the PinNumber property set to 1.
> However, that is not correct. If you use setService(class, filter) and you
> specify both, DM (both version 3 and the just released version 4) will
> construct a filter for you consisting of both the ObjectClass and the
> conditions you specify. So the code above will work, it will just have a
> filter for ObjectClass twice. ;)
>
> Greetings, Marcel
>
>
>
>

Re: Dependency Manger - multiple instances of service

Posted by Marcel Offermans <ma...@luminis.nl>.
Hello Angelo, Jan,

In general, Angelo is completely right, but there is one thing in his response that is not:

.setService(IGPIOPin.class, "&((" + Constants.OBJECTCLASS + "=" + IGPIOPin.class.getName() + ")(PinNumber=1))") 
.setRequired(true) 
.setAutoConfig("fanPin")) 
In the code above, Angelo added the ObjectClass to the filter, because:

Remember to include the ObjectClass in the filter, as you override the service filter that would normally be created, and you could end up with any other service that has the PinNumber property set to 1. 
However, that is not correct. If you use setService(class, filter) and you specify both, DM (both version 3 and the just released version 4) will construct a filter for you consisting of both the ObjectClass and the conditions you specify. So the code above will work, it will just have a filter for ObjectClass twice. ;)

Greetings, Marcel




Re: Dependency Manger - multiple instances of service

Posted by Angelo van der Sijpt <an...@luminis.eu>.
Hi Jan,

If you have a dependency on two services of the same type, you can use the setAutoConfig(String) property on the dependency: this allows you to set the name of the member you want the dependency injected into.

So, given a consumer class

	class PinConsumer {
		private volatile IGPIOPin fanPin; 
		private volatile IGPIOPin dispenserPin;
		
		// And more!
	}

you would have Activator code that looks like 

	dependencyManager.add(createComponent()
            .setInterface(Object.class.getName(), null)
            .setImplementation(PinConsumer.class)
            .add(createServiceDependency()
                    .setService(IGPIOPin.class, "&((" + Constants.OBJECTCLASS + "=" + IGPIOPin.class.getName() + ")(PinNumber=1))")
                    .setRequired(true)
                    .setAutoConfig("fanPin"))
            .add(createServiceDependency()
                    .setService(IGPIOPin.class, "&((" + Constants.OBJECTCLASS + "=" + IGPIOPin.class.getName() + ")(PinNumber=2))")
                    .setRequired(true)
                    .setAutoConfig("dispenserPin"))
            .add(createServiceDependency().setService(LogService.class)));	

Remember to include the ObjectClass in the filter, as you override the service filter that would normally be created, and you could end up with any other service that has the PinNumber property set to 1.

Angelo



> On 11 Mar 2015, at 22:46, Jan J. Roman <po...@jjroman.net> wrote:
> 
> Hello,
> 
> I am exploring possibility of using felix and osgi in general for
> developing home automation project on raspberry pi.
> 
> I created PinService of which one instance reflects one physical pin on
> RPI. Instances are identified by property value. Now I am building service
> which relay on two pins so I need two instances of PinServiceImpl in one
> activator.
> 
> I am using Felix Dependency Manager to simplify dependencies and to inject
> services. Below is a code that I am working with however it is not ideal as
> it uses two different classes to inject one service to each class. I would
> like to have two instances injected into one class.
> 
> Is there out of the box way to achieve this?
> Is there better way to manage dependencies in osgi & felix?
> 
> in Activator:
> 
> public void init(BundleContext bundleContext, DependencyManager
> dependencyManager) throws Exception {
>        {
> dependencyManager.add(createComponent()
>                            .setInterface(Object.class.getName(), null)
>                            .setImplementation(PinConsumerFan.class)
>                            .add(createServiceDependency()
>                                    .setService(IGPIOPin.class,
> "(PinNumber=1)")
>                                    .setRequired(true))
> 
> .add(createServiceDependency().setService(LogService.class))
>            );
> dependencyManager.add(createComponent()
>                            .setInterface(Object.class.getName(), null)
>                            .setImplementation(PinConsumerDispenser.class)
>                            .add(createServiceDependency()
>                                    .setService(IGPIOPin.class,
> "(PinNumber=2)")
>                                    .setRequired(true))
> 
> .add(createServiceDependency().setService(LogService.class))
>            );
> }
> 
> Thanks in advance for any hints.
> 
> Regards
> Jan Roman


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org