[ 
https://issues.apache.org/jira/browse/FELIX-5336?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15736700#comment-15736700
 ] 

Pierre De Rop commented on FELIX-5336:
--------------------------------------

Hi Jan Willem,

I have something working. can you please try it ?
I have attached to this issue FELIX-5336.tgz (it's not a diff, but a tar.tgz of 
the modified/added files).

so, to install, first checkout dm from the trunk, then cd to dependencymanager 
, and tar zxvf FELIX-5336.tgz
(the tar.gz contains some more fix for other issues , I will create more JIRA 
issues soon about them).

now, in the 
org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/servicescope/api/,
 there is a demo.

I'm now describing the model used (a bit different from the one initially 
described in this issue).

So, to create a scoped service component, you can now invoke the 
createComponent(ComponentPolicy) method.
The policy is an enum allowing to define a strategy about how components are 
created.
you can also use the policy for all adapters, and for aspects.

this enum contains the following (it is actually only used when the component 
is a service provider):

- ComponentPolicy.SINGLETON: -> singleton component, as usual.
- ComponentPolicy.BUNDLE -> an instance of the component must be created for 
each bundle using the service. it actually corresponds to a ServiceFactory
- ComponentPolicy.BUNDLE_DYNAMIC: same as ComponentPolicy.BUNDLE, but allows to 
define a component which can add some dynamic dependencies from its init/start 
callback.
- ComponentPolicy.PROTOTYPE -> an instance of the component must be created for 
each distinct request for the service. it actually corresponds to a 
PrototypeServiceFactory
- ComponentPolicy.PROTOTYPE_DYNAMIC: same as ComponentPolicy.BUNDLE, but allows 
to define a component which can add some dynamic dependencies from its 
init/start callback.


So, for BUNDLE, and PROTOTYPE, a hidden component will track dependencies, and 
will register a ServiceFactory, or a PrototypeServiceFactory, respectively. 

when a component instance is created (because there is a requester for the 
service), then the component will be injected with the bundle / service 
registration (if it defines a Bundle or a ServiceRegistration field). This 
parameters correspond to the ones passed to the actual Service 
ServiceFactory.getService (or PrototypeServiceFactory.getService) methods.

So, if your scoped service provider component is dynamic (it may add some 
dynamic dependencies from the init or start callback), then you can use one of 
the two
constants from the enum:

BUNDLE_DYNAMIC, or PROTOTYPE_DYNAMIC.

In this case, a prototype instance component is always created (singleton), it 
will then be called as a regular DM component, and will add any dynamic 
dependencies it is necessary to add from the init or start callbacks. And once 
fully started (all required + instance bound dependencies injected), then the 
corresponding ServiceFactory or PrototypeServiceFactory will then be 
registered. And when a requester will define a dependency on the service, a 
copy of the prototype component instance will be created and returned by the 
ServiceFactory.getService (or PrototypeServiceFactory.getService) methods. 
Notice that the prototype component instance (singleton) won't be injected with 
the "Bundle" or "ServiceRegistration" parameters. This will allow you to detect 
if your component is the prototype instance or if it's a clone being created 
and returned to the requesting service.

In the demo (see 
org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/servicescope/api/),
 you have a Provider which is a prototype scope service: it does not add some 
dynamic dependencies from its init/start callbacks. So, there is now two Client 
instances which get injected with their own copy of the ProviderImpl.

You also have a DynamicProvider: it is a scoped service (PROTOTYPE_DYNAMIC), 
and the prototype instance is first created in order to add a dynamic 
dependency from the init method.
and once started, then the corresponding PrototypeServiceFactory will be 
registered.

At this point, a ConsumerUsingServiceObjects component will be started, and in 
this example, unlike from the Client example, A ServiceReference to the 
DynamicProvider is injected. I did not have time to inject a ServiceObjects 
directly. So for now, if you need to manually create some instances, you have 
to use the ref in order to get the ServiceObjects. Then from the 
ConsumerUsingServiceObjects.start() method, two instances of the 
DynamicProvider component  are created, and deleted from the stop() method.

one important remark: when you are using ServiceReference, by default the 
Component for the ConsumerUsingServiceObjects  will aquire an instance of the 
DynamicProvider.
for the moment, I don't have added some complexity in the state machine in 
order to detect that you actually only need to get injected with a 
ServiceReference (and not with the service itself). So, in order to avoid 
having a DynamicProvider automatically dereferenced by the 
ConsumerUsingServiceObjects Component (internally), you will see in the demo 
Activator that I have introduced  a new "dereference(boolean)" method in the 
ServiceDependency interface: it allows you to tell to DM that you don't want 
your component to automatically dereference the injected service internally, 
because all you want is the just the ServiceReference, not the actual service. 
So, please for now, use the dereference(boolean) method. (see the Activator in 
the demo).

Please tell me what you think about all this, and I can then possibly make a 
release soon.
thanks a lot.

> Add support for prototype scope services in DM4
> -----------------------------------------------
>
>                 Key: FELIX-5336
>                 URL: https://issues.apache.org/jira/browse/FELIX-5336
>             Project: Felix
>          Issue Type: New Feature
>          Components: Dependency Manager
>    Affects Versions: org.apache.felix.dependencymanager-r8
>            Reporter: Pierre De Rop
>            Assignee: Pierre De Rop
>             Fix For: org.apache.felix.dependencymanager-r9
>
>         Attachments: PrototypeServiceFactoryTest.java
>
>
> In the users mailing list, there is a wish to add support in DM4 for OSGi 
> prototype scope services, which allows any service consumer to get its own 
> instance of a given service dependency.
> See http://www.mail-archive.com/[email protected]/msg17473.html



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to