Setting properties on component instantiate

4 views
Skip to first unread message

project2501

unread,
Mar 8, 2017, 4:32:53 AM3/8/17
to ipopo-users
Hi again,
   I am wondering how properties are set when instantiating a component via ipopo service. I see the docs say this:

instantiate(factory_namenameproperties=None)

Yet on the same page this example is given, without the kwarg.
with use_ipopo(context) as ipopo:
    # use the iPOPO core service with the "ipopo" variable
    ipopo.instantiate("my.factory", "my.component", {})

 I tried both approaches and when my component @Validate method gets hit, none of the key:value properties I pass in are set on the instance.

What am I missing here?

thank you for your time.
 

Thomas Calmant

unread,
Mar 8, 2017, 4:56:10 AM3/8/17
to ipopo...@googlegroups.com
Hi,

Properties is an optional dictionary argument.
A better example would be:

with use_ipopo(context) as ipopo:
    ipopo.instantiate("my.factory", "my.component", {"some.property": 42, "another": [1, 2, 3]})

Those properties are associated to the component and can be seen through the Pelix shell with the "instance <name>" command.
If a dictionary key matches a property defined on the component factory with an @Property decorator, the value will be injected at instantiation.
Else, the property is associated to the component which can't be access it: this is useful to export the service(s) of a component without having to explicitely declare the export properties on each factory.

Cheers,
Thomas


--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes "ipopo-users".
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse ipopo-users+unsubscribe@googlegroups.com.
Pour obtenir davantage d'options, consultez la page https://groups.google.com/d/optout.

Darren G

unread,
Mar 8, 2017, 5:06:18 AM3/8/17
to ipopo...@googlegroups.com
Thanks Thomas. It seems it's not working for me as you describe. Because that's what I was expecting. I will dig deeper to determine what the problem might be and do a separate test to see if it's behaving correctly there.

I'm not seeing the instance properties getting set after validation at the moment and traced my code to ensure the arguments are being sent.

Thomas Calmant

unread,
Mar 8, 2017, 5:13:38 AM3/8/17
to ipopo...@googlegroups.com
That's strange.
Note that if you are using Python 2, it is necessary that the component factories explicitly inherit from "object".

Darren G

unread,
Mar 8, 2017, 5:23:24 AM3/8/17
to ipopo...@googlegroups.com
Yep. Mine inherits from object. I'm scratching my head because I see the props going into ipopo.instantiate and then my debugger breaks on the component @Validate method. No properties set. Let me try to isolate it and post my findings.
Message has been deleted

project2501

unread,
Mar 8, 2017, 5:56:35 AM3/8/17
to ipopo-users
Here is my test. I'm probably missing something obvious but self.title does not get set on the component and it is None when I try to access it in @Validate. thanks for your help!

ipopotest.py
---------------------

from pelix.ipopo.decorators import *
import pelix.ipopo.constants as constants
from pelix.ipopo.constants import IPOPO_SERVICE_SPECIFICATION

from pelix.ipopo.constants import use_ipopo


@ComponentFactory(name="CFRComponentFactory")
@Property("name", constants.IPOPO_INSTANCE_NAME)
@Property("thread_safe", "thread.safe", False)
@Property("usable", "usable", True)
@Provides(specifications="my.cfr")
class CFRComponent(object):


    def __init__(self):
        pass

    @Validate
    def validate(self, context):
        print "TITLE:",self.title

if __name__ == '__main__':
    import pelix.framework as pelix

    from pelix.ipopo.constants import IPOPO_SERVICE_SPECIFICATION

    print IPOPO_SERVICE_SPECIFICATION

    # Start framework
    framework = pelix.FrameworkFactory.get_framework()
    framework.start()

    context = framework.get_bundle_context()
    bundle_id = context.install_bundle("pelix.ipopo.core")
    bundle = context.get_bundle(bundle_id)
    bundle.start()
    ipopo_ref = context.get_service_reference(IPOPO_SERVICE_SPECIFICATION)
    ipopo = context.get_service(ipopo_ref)

    bundle_id = context.install_bundle("ipopotest")
    bundle = context.get_bundle(bundle_id)
    bundle.start()

    try:
        cfr = ipopo.instantiate("CFRComponentFactory", "cfrobj", {"title":"the title"})
    except:
        print traceback.format_exc()
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse ipopo-users...@googlegroups.com.

Pour obtenir davantage d'options, consultez la page https://groups.google.com/d/optout.

--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes "ipopo-users".
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse ipopo-users...@googlegroups.com.

Pour obtenir davantage d'options, consultez la page https://groups.google.com/d/optout.

--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes "ipopo-users".
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse ipopo-users...@googlegroups.com.

Thomas Calmant

unread,
Mar 8, 2017, 6:40:55 AM3/8/17
to ipopo...@googlegroups.com
OK, so it's the expected behaviour./
In order to access the property from within the component, you have to declare it with @Property:

@ComponentFactory(name="CFRComponentFactory")
@Property("name", constants.IPOPO_INSTANCE_NAME)
@Property("thread_safe", "thread.safe", False)
@Property("usable", "usable", True)
@Property("title", "title", "No Title") # <------------- This is necessary
@Provides(specifications="radiant.find.components.cfr")
class CFRComponent(object):
    def __init__(self):
        pass

    @Validate
    def validate(self, context):
        print "TITLE:",self.title

Without it, the "title" property will be associated to the instance, but won't be accessible by it: it will be accessible using iPOPO reflections and visible as a property for all services provided by the instance.

Adding a property using instantiate is OK when it's a "meta"-property, like adding the export properties for Remote Services.
BUT, adding a property to the instance can't be done this way: it's too late for iPOPO to inject the property in the class and it also reduces the readability of the code, as you access members that are not defined in the component factory.

Cheers,
Thomas


Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse ipopo-users+unsubscribe@googlegroups.com.

project2501

unread,
Mar 8, 2017, 7:48:36 AM3/8/17
to ipopo-users
Ahhhh, very well then. :)

Thank you for clarifying!

Thomas Calmant

unread,
Mar 9, 2017, 11:43:20 AM3/9/17
to ipopo...@googlegroups.com
Hi,

I've added some notes about this behaviour in the documentation of @Instantiate.

Cheers,
Thomas


Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse ipopo-users+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages