|The PEAK Developers' Center||FrontPage||RecentChanges||TitleIndex||WordIndex||SiteNavigation||HelpContents|
The following is adapted from a thread on the PEAK mail list regarding components for beginners.
From http://www.eby-sarna.com/pipermail/peak/2004-September/001778.html :
There has to be motivation for needing to *replace* certain components with others, like putting a bigger power supply into a microwave oven to support a bigger cooking compartment. The possibility of replacement is one of the biggest motivating factors in determining how responsibilities are separated into components.
Placement is determined by who needs the component; what is it's scope? The buttons on a microwave oven are used only within the "control panel" component, but the "power supply" is used throughout. Therefore, "power supply" is a child of microwave oven. "Control Panel" would 'Make' buttons, but 'Obtain' a power supply from its parent component, the oven.
So, place components at the scope of their use, "offering" them to any child components that require their services, e.g.:
class MicrowaveOvenModel263(binding.Component): powerSupply = binding.Make(MediumPowerSupply, offerAs=[IPowerSupply]) controlPanel = binding.Make("cpanels.ControlPanelType2", offerAs=[IControlPanel]) radiativeElement = binding.Make(Radartronic263, offerAs=[IRadiative]) class ControlPanelType2(binding.Component): powerSupply = binding.Obtain(IPowerSupply) button0 = binding.Make(Button) # ...
Regarding building components and ways to think about 'binding.Obtain' and 'binding.Make'.
Q: When would I choose Make over Obtain? and vice versa?
A: Obtain can access the "binding" system, the "configuration" system, or the "naming" system, depending on what argument you give. As a general rule, accessing the binding or configuration systems will cause Obtain to provide existing components, and accessing the naming system will produce a new component. But there are exceptions, especially since you can create your own 'binding.IComponentKey' implementations for use with 'Obtain', and they can do whatever you want.
But the general idea of Obtain is, "I know this is out there somewhere, go get it for me".
Make, on the other hand, generally means, "make me one of these". But again, you can create your own 'binding.IRecipe' implementations that do whatever you want, so there are exceptions to that rule as well. You can also apply 'Make' to any function or lambda, so the possibilities of what it can do are endless. In a way, 'Obtain' is a specialization of 'Make' that just looks things up instead of making them.
From a question to the mail list about adding component children at runtime and related configurations.
From http://www.eby-sarna.com/pipermail/peak/2004-September/001746.html :
Q: I would like to add Component-children to a component at runtime, as well as advertise those components to other children under certain Interfaces or configuration paths. How do I do this?
A: Are the interfaces different each time, or is there a set of N interfaces with N instances that always occur?
If the latter, just define bindings like this:
child1 = binding.Require("This is where child 1 goes", offerAs=[Interface1])And set the 'child1' attribute at runtime.
If you don't know what interfaces you're using until runtime, then you need to have the parent subclass 'binding.Configurable' instead of 'binding.Component', and you'll use the parent's 'registerProvider()' method to register child components. See 'peak.config.interfaces' for more details, especially IConfigurable and IRule.
The following tidbit is from the beginning of a thread concerning naming.lookup() vs config.lookupComponent().
From http://www.eby-sarna.com/pipermail/peak/2004-June/001541.html :
Q: What is the difference between root.lookupComponent() and naming.lookup()?
A: By default, anObj.lookupComponent() "suggests" to the found component that 'anObj' is the found component's "parent"; component.naming.lookup() just looks up the object in question.