[PEAK] Using attribute bindings within constructor when using
Component Factories
Wayne Larsen
wayne at larsen.st
Sun Jan 18 01:49:31 EST 2004
Thanks for the response,
The problem I had with assembly events, is that there does not seem to
be any guarantee of order given an inheritance structure. So, for example:
class TestService(binding.Component):
protocols.advise(
instancesProvide=[ITestService]
)
log = binding.Obtain('logger:TestService')
message = binding.Obtain(PropertyName('helloworld.message'))
def __init(self):
self.log.info('from Parent __init: %s' % self.message)
__init = binding.Make(__init, uponAssembly=1)
def hello(self):
self.log.info(self.message)
class ChildTestService(TestService):
def __init(self):
self.log.info('from Child __init: %s' % self.message)
__init = binding.Make(__init, uponAssembly=1)
class GrandChildTestService(ChildTestService):
def __init(self):
self.log.info('from GrandChild __init: %s' % self.message)
__init = binding.Make(__init, uponAssembly=1)
class Test(running.commands.AbstractCommand):
log = binding.Obtain('logger:helloworld')
ts = binding.Obtain(ITestService)
def _run(self):
self.ts.hello()
The output of this gives me:
GrandChildTestService[5161]: from Parent __init: Hello, world!
GrandChildTestService[5161]: from GrandChild __init: Hello, world!
GrandChildTestService[5161]: from Child __init: Hello, world!
GrandChildTestService[5161]: Hello, world!
The problem here is converting an existing application. The "normal"
way of doing this is to put all intialization into your constructor.
This initialization means setting themselves up based on data that I
want to move into config files. If those classes depend on the base
class initalizing first, I am unsure whether I can rely on assembly
events. Is there any guarantee of order for assembly events?
Thanks,
Wayne
Phillip J. Eby wrote:
> So, really, that boils down to "don't override the constructor unless
> you're doing something that does no lookups", or just, "don't override
> the constructor".
>
> Instead, you should be using "assembly events". For example, if you
> wanted your TestService to log a message as soon as it's "snapped into"
> the application, you could add:
>
> def __logStartup(self):
> self.log.info(self.message)
>
> __logStartup = binding.Make(__logStartup, uponAssembly=True)
>
> Then, as soon as the service knows its parent (and the parent knows its
> parent, and so on up to a "known root" component (a component that knows
> it has no parents), the __logStartup method will be called. This is
> much better than overriding the constructor, since you can access any
> attributes and do any lookups with full access to your parent components.
>
More information about the PEAK
mailing list