I’m assuming that this isn’t very close to the actual code. If it is then this 
has a significant leak. Each time you create a ComponentInstance instance from 
the ComponentFactory then you must dispose of it when you are done. If you 
don’t then these instances will accumulate over time.

Is the MyServiceFactory declared in the same bundle as the MyService? If so, 
and if the “Config” is not allowed to change the target filter(s) of the 
MyService instance then I would strongly recommend not using a component 
factory, but instead directly instantiating the MyServiceImpl, setting it up in 
the “get” method. This will mean that you don’t need to worry about the objects 
being leaked because the only person holding them is the client.

Best Regards,

Tim

> On 9 Jul 2018, at 09:36, David Leangen <o...@leangen.net> wrote:
> 
> 
> Just some feedback…
> 
> This really worked nicely for me:
> 
> public class MyServiceFactory {
>   @Reference(target=...)
>   ComponentFactory cf;
> 
>   MyService get(Config config) {
>     Dictionary props = config.toProps();
>     ComponentInstance ci = cf.newInstance(props);
>     MyService myService = (MyService) ci.getInstance();
>     return myService;
>   }
> }
> 
> The consumers then do this:
> 
> public class SomeMyServiceConsumer {
> 
>   @Reference(target=...)
>   MyServiceFactory msf;
> 
>   void someMethod() {
>     Config config = …
>     MyService ms = msf.get(config);
>     ...
>   }
> }
> 
> The only addition I had to make was, because there are actually several 
> MyServiceFactories that provide different implementations, to add a target 
> property to the MyServiceFactory @Reference. (Actually, the target is 
> configured in a configuration using the msf.target property, which is also 
> quite nice!
> 
> Very nice and clean solution. Thanks for pointing this out!
> 
> 
> Cheers,
> =David
> 
> 
> 
>> On Jul 5, 2018, at 7:56, David Leangen via osgi-dev <osgi-dev@mail.osgi.org 
>> <mailto:osgi-dev@mail.osgi.org>> wrote:
>> 
>> 
>> Thanks to Dirk, Tim, and Christian for your replies.
>> 
>> That gives me plenty of options. Some very nice insights.
>> 
>> Cheers!!
>> 
>> 
>> =David
>> 
>> 
>> 
>>> On Jul 4, 2018, at 17:51, Tim Ward <tim.w...@paremus.com 
>>> <mailto:tim.w...@paremus.com>> wrote:
>>> 
>>> Hi David,
>>> 
>>> There are some approaches that may help, but it’s not 100% clear from this 
>>> thread which is correct for you because the scenario isn’t fully fleshed 
>>> out. It appears that you are either:
>>> 
>>> 1) In need of your own specific instance of a common stateful, or otherwise 
>>> thread unsafe, service which you want to instantiate and then release. Many 
>>> instances may be needed concurrently, but the configuration is all the same.
>>> 2) In need of your own specially configured instance of a service, which 
>>> should not be used by anyone else
>>> 3) Something else...
>>> 
>>> 
>>> The solution to 1) is to use a prototype scoped service. Prototype scoped 
>>> services allow the client to request and release instances on demand. You 
>>> can use prototype scoped services in DS by injecting a 
>>> ComponentServiceObjects.
>>> 
>>> 
>>> @Reference
>>> ComponentServiceObjects<MyService> cso;
>>> 
>>> void someMethod() {
>>>  if (someCondition) {
>>>     // Do one thing
>>>  } else {
>>>     MyService myService = cso.getService()
>>>     
>>>     // Use the service
>>>     
>>>     cso.ungetService(myService);
>>>  }
>>> }
>>> 
>>> 
>>> The solution to 2) is either to a) use a DS ComponentFactory, or b) accept 
>>> that the API of your service needs to change.
>>> 
>>> DS Component Factories are not widely used, but they provide a mechanism to 
>>> programatically “stamp out” DS component instances from a template:
>>> 
>>> @Reference(target=(component.name=your.component)
>>> ComponentFactory cf;
>>> 
>>> void someMethod() {
>>>  if (someCondition) {
>>>     // Do one thing
>>>  } else {
>>>     ComponentInstance ci = cf.newInstance(props);
>>> 
>>>     MyService myService = (MyService) ci.getInstance()
>>>     
>>>     // Use the service
>>>     
>>>     ci.dispose();
>>>  }
>>> }
>>> 
>>> On the other hand for 2 b) you could just change the way that your Service 
>>> API works…
>>> 
>>> @Reference
>>> MyServiceFactory msf;
>>> 
>>> void someMethod() {
>>>  if (someCondition) {
>>>     // Do one thing
>>>  } else {
>>>     MyService myService = msf.getMyService(props);
>>>     
>>>     // Use the service
>>>     
>>>     // Do you really need a dispose? The GC could probably take care of it.
>>>  }
>>> }
>>> 
>>> Advantages of Component Factories
>>> 
>>> No need to track any references, each instance is separate and DS takes 
>>> care of it
>>> Your component can run (mostly) unchanged, just set factory=true in your 
>>> @Component annotation
>>> 
>>> Disadvantages of Component Factories
>>> 
>>> Your consumers are now tied to the DS API
>>> You have leaked implementation detail about how your bundle provides its 
>>> “service”
>>> You have to rely on configuration for type safety
>>> You have no easy way to share common configuration between the instances
>>> The configuration you supply may cause lifecycle issues (if you customise a 
>>> target filter then it may not be satisfiable on demand) 
>>> 
>>> 
>>> My preference is always to lean toward 2 b) rather than 2 a). Typically the 
>>> “specialisation” in configuration needed for each client is a small tweak 
>>> to an otherwise constant central configuration. Also I find that I often 
>>> have common resources (e.g. thread pools) that it doesn’t make sense to 
>>> create and destroy repeatedly. The MyServiceFactory is then just a simple 
>>> type which instantiates a MyServiceImpl, passing in any necessary backing 
>>> services/objects/additional configuration as needed.
>>> 
>>> I hope this helps to widen your available options.
>>> 
>>> Best Regards,
>>> 
>>> Tim
>>> 
>>> 
>>>> On 4 Jul 2018, at 07:13, David Leangen via osgi-dev 
>>>> <osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>> wrote:
>>>> 
>>>> 
>>>> Thank you Dirk, those are very nice posts. I have come across these in the 
>>>> past and thought they were very informative.
>>>> 
>>>> If I am not mistaken, each of the methods you mention requires a 
>>>> @Reference. In this case, I am looking for a way to instantiate a service 
>>>> instance inline.
>>>> 
>>>> Example:
>>>> 
>>>> 
>>>> void someMethod() {
>>>>  if (someCondition) {
>>>>     // Do one thing
>>>>  } else {
>>>>     // Instantiate the required service using ConfigAdmin — don’t use 
>>>> @Reference here because it is done inline
>>>>     // Use the service
>>>>     // Delete the configuration, which will deactivate the service
>>>>  }
>>>> }
>>>> 
>>>> It is the meme above that I am not satisfied with:
>>>> 
>>>>  1. Activate a service instance by creating a Configuration
>>>>  2. Locate that specific service instance and use it
>>>>  3. Delete the Configuration to deactivate the service instance
>>>> 
>>>> 
>>>> Unless of course there is a clever way to use @Reference that I am missing 
>>>> which would provide an alternative means of accomplishing this.
>>>> 
>>>> 
>>>> Best regards,
>>>> =David
>>>> 
>>>> 
>>>> 
>>>>> On Jul 4, 2018, at 14:45, Fauth Dirk (AA-AS/EIS2-EU) 
>>>>> <dirk.fa...@de.bosch.com <mailto:dirk.fa...@de.bosch.com>> wrote:
>>>>> 
>>>>> Hi,
>>>>> 
>>>>> not sure about your use case in detail, but it sounds like you either 
>>>>> could use the ConfigurationAdmin approach like I explained here: 
>>>>> http://blog.vogella.com/2017/02/13/control-osgi-ds-component-instances/ 
>>>>> <http://blog.vogella.com/2017/02/13/control-osgi-ds-component-instances/>
>>>>> Probably that is what you have already tried.
>>>>> 
>>>>> But maybe the target reference property is what satisfies your need in a 
>>>>> more easy way. I explained that at the bottom of a blog post here: 
>>>>> http://blog.vogella.com/2016/09/26/configuring-osgi-declarative-services/ 
>>>>> <http://blog.vogella.com/2016/09/26/configuring-osgi-declarative-services/>
>>>>> 
>>>>> As an alternative you could also try if the available DS mechanisms would 
>>>>> help, like servicefactory, scope or factory. I explained that here: 
>>>>> http://blog.vogella.com/2017/02/13/control-osgi-ds-component-instances/ 
>>>>> <http://blog.vogella.com/2017/02/13/control-osgi-ds-component-instances/>
>>>>> 
>>>>> From your question that you want to request one special instance, I 
>>>>> suppose the target property on a reference is what you need, but there 
>>>>> are several ways for different scenarios. :)
>>>>> 
>>>>> Mit freundlichen Grüßen / Best regards
>>>>> 
>>>>> Dirk Fauth
>>>>> 
>>>>> Automotive Service Solutions, ESI application (AA-AS/EIS2-EU) 
>>>>> Robert Bosch GmbH | Postfach 11 29 | 73201 Plochingen | GERMANY | 
>>>>> www.bosch.com <http://www.bosch.com/>
>>>>> Tel. +49 7153 666-1155 | dirk.fa...@de.bosch.com 
>>>>> <mailto:dirk.fa...@de.bosch.com>
>>>>> 
>>>>> Sitz: Stuttgart, Registergericht: Amtsgericht Stuttgart, HRB 14000; 
>>>>> Aufsichtsratsvorsitzender: Franz Fehrenbach; Geschäftsführung: Dr. 
>>>>> Volkmar Denner, 
>>>>> Prof. Dr. Stefan Asenkerschbaumer, Dr. Michael Bolle, Dr. Rolf Bulander, 
>>>>> Dr. Stefan Hartung, Dr. Markus Heyn,
>>>>> Dr. Dirk Hoheisel, Christoph Kübel, Uwe Raschke, Peter Tyroller
>>>>> 
>>>>> 
>>>>> -----Ursprüngliche Nachricht-----
>>>>> Von: osgi-dev-boun...@mail.osgi.org 
>>>>> <mailto:osgi-dev-boun...@mail.osgi.org> 
>>>>> [mailto:osgi-dev-boun...@mail.osgi.org 
>>>>> <mailto:osgi-dev-boun...@mail.osgi.org>] Im Auftrag von David Leangen via 
>>>>> osgi-dev
>>>>> Gesendet: Mittwoch, 4. Juli 2018 07:12
>>>>> An: osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>
>>>>> Betreff: [osgi-dev] DS factory-type pattern
>>>>> 
>>>>> 
>>>>> Hi,
>>>>> 
>>>>> This may be another really dumb question… but is there a smart way to use 
>>>>> DS as a kind of factory?
>>>>> 
>>>>> What I have been doing so far:
>>>>> 
>>>>> * Creating a Configuration via ConfigurationAdmin (I need to configure my 
>>>>> component first)
>>>>> * In the config, including a kind of “secret” so I know which is MY 
>>>>> instance
>>>>> * Listening for the existence of a service (which includes the secret)
>>>>> 
>>>>> 
>>>>> It works very well, but there is a bit more cruft then I would like, and 
>>>>> it doesn’t seem as elegant as it ought to.
>>>>> 
>>>>> 
>>>>> Am I missing something, or is this the “right” was to do it at this time?
>>>>> 
>>>>> 
>>>>> Cheers,
>>>>> =David
>>>>> 
>>>>> 
>>>>> _______________________________________________
>>>>> OSGi Developer Mail List
>>>>> osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>
>>>>> https://mail.osgi.org/mailman/listinfo/osgi-dev 
>>>>> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
>>>> 
>>>> _______________________________________________
>>>> OSGi Developer Mail List
>>>> osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>
>>>> https://mail.osgi.org/mailman/listinfo/osgi-dev 
>>>> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
>> 
>> _______________________________________________
>> OSGi Developer Mail List
>> osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>
>> https://mail.osgi.org/mailman/listinfo/osgi-dev
> 

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to