Next: Namespaces, Previous: Interface and Component Behaviour, Up: Dezyne Syntax [Contents][Index]
A component which is composed from a number of sub components has a ’system’ internal description. This description specifies the available sub component instances, and all connections between the component ports. An example: suppose the following components to be defined:
component Foo { provides IFoo foo; requires IBar bar; requires INut nut; // ... internals ... } component Bar { provides IBar b; // ... internals ... } component Nut { provides INut nt; requires IWell wl; // ... internals ... }
Then a system component MySys
could be defined:
component MySys { provides IFoo top; requires IWell bot; // ... internals ... }
where its internals are composed of the Foo
, Bar
, and
Nut
components:
component MySys { provides IFoo top; requires IWell bot; system { Foo cfoo; Bar cbar; Nut cnut; top <=> cfoo.foo; cfoo.bar <=> cbar.b; cfoo.nut <=> cnut.nt; cnut.wl <=> bot; } }
The system description shows the instantiation of the three sub components, and four connections between various ports.
In a system description a sub component is specified by its type and local name:
MyComponent myInstance;
The definition of MyComponent has to be available, potentially through an ’import’.
It is allowed to have more than one instance of the same type:
MyComponent myInstance1; MyComponent myInstance2;
Communication between components is achieved through component ports. Communication is specified as binding:
MyComp1.port1 <=> MyComp2.port2;
indicates components MyComp1
and MyComp2
communicate
through their respective ports port1
and port2
. This is
often expressed as: port1
is bound to port2
.
Binding is symmetric: MyComp1.port1 <=> MyComp2.port2
and
MyComp2.port2 <=> MyComp1.port1
have identical meaning.
Communication is restricted to ports of the same (interface) type. Moreover communication ’direction’ has to be preserved. There are two cases:
provides
port binds to
a requires
port, like in cfoo.bar <=> cbar.b
in the example
above.
top <=>
cfoo.foo
and cnut.wl <=> bot
in the example above.
Binding of injected
ports is done at a higher system level
(see Component Models). A wild-card character (*
) is used to
achieve the binding of one provides
port to all injected
requires
ports.
Let’s take a typical example involving logging:
interface ILog { ... } component Log { provides ILog log; ... }
Suppose a lot of components require logging:
... component MyComponent12 { provides MyInterface12 intf; requires injected ILOg l; ... } component MyComponent13 { provides MyInterface13 intf; requires injected ILOg l; ... } ...
then some system component can bind all logging in one go:
component MySystem { ... system { Log clog; ... MyComponent12 c12; MyComponent13 c13; ... clog.log <=> *; } }
It is allowed to group some components in a sub system:
component MySubSystem { ... system { ... MyComponent12 c12; MyComponent13 c13; ... } }
and do the wild-card binding for that sub system only:
component MySystem { ... system { Log clog; MySubSystem subsys; ... clog.log <=> subsys.*; } }
Next: Namespaces, Previous: Interface and Component Behaviour, Up: Dezyne Syntax [Contents][Index]