Bindings and Data Context
The Matrix Framework uses bindings to create connections between services and propagate data through the service tree.
Data Context
Context Inheritance
Services inherit data context from their parents:
<ServiceNode Name="OrderSystem">
<!-- Set data context for all child services -->
<ServiceNode.DataContext>
<OrderSystemContext>
<Property Name="CurrentUser" Value="{Binding User}" />
<Property Name="Settings" Value="{Binding AppSettings}" />
</OrderSystemContext>
</ServiceNode.DataContext>
<ServiceNode Name="OrderProcessor">
<!-- Inherits OrderSystemContext -->
<MessageHandler Path="/orders/create">
<!-- Access inherited context -->
<ValidateUser User="{Binding CurrentUser}" />
<ApplySettings Settings="{Binding Settings}" />
</MessageHandler>
</ServiceNode>
</ServiceNode>Context Overriding
Services can override inherited context:
<ServiceNode Name="PaymentProcessor">
<!-- Override specific context properties -->
<ServiceNode.DataContext>
<Property Name="PaymentSettings"
Value="{Binding Settings.Payment}" />
<Property Name="MerchantId"
Value="{Binding Settings.MerchantId}" />
</ServiceNode.DataContext>
</ServiceNode>Binding Types
Property Binding
Bind service properties to data context:
<ServiceNode Name="OrderProcessor">
<!-- Bind service properties -->
<ServiceNode.Properties>
<Property Name="MaxOrderSize"
Value="{Binding Settings.MaxItems}" />
<Property Name="ValidationRules"
Value="{Binding Rules.Order}" />
</ServiceNode.Properties>
<!-- Use bound properties -->
<MessageHandler Path="/orders/create">
<ValidateOrder MaxItems="{Binding MaxOrderSize}"
Rules="{Binding ValidationRules}" />
</MessageHandler>
</ServiceNode>Message Binding
Bind message data to handlers:
<ServiceNode Name="OrderManager">
<MessageHandler Path="/orders/create">
<!-- Bind message properties -->
<Parameter Name="OrderData"
Value="{Binding Message.Body}" />
<Parameter Name="CustomerId"
Value="{Binding Message.Headers.CustomerId}" />
<!-- Two-way binding for response -->
<Response Path="/orders/created">
<Property Name="OrderId"
Value="{Binding Result.Id, Mode=TwoWay}" />
<Property Name="Status"
Value="{Binding Result.Status, Mode=TwoWay}" />
</Response>
</MessageHandler>
</ServiceNode>Command Binding
Bind commands to message handlers:
<ServiceNode Name="OrderAPI">
<!-- Define commands -->
<ServiceNode.Commands>
<Command Name="CreateOrder"
CanExecute="{Binding Permissions.CanCreateOrder}">
<Parameter Name="OrderData" />
<Parameter Name="CustomerId" />
</Command>
</ServiceNode.Commands>
<!-- Bind commands to messages -->
<MessageHandler Path="/api/orders/create"
Command="{Binding Commands.CreateOrder}">
<CommandParameter Name="OrderData"
Value="{Binding Message.Body}" />
<CommandParameter Name="CustomerId"
Value="{Binding Message.User.Id}" />
</MessageHandler>
</ServiceNode>Binding Modes
One-Way Binding
Data flows in one direction:
<ServiceNode Name="MetricsCollector">
<!-- One-way binding from source -->
<Property Name="OrderCount"
Value="{Binding Source.Metrics.Orders, Mode=OneWay}" />
<!-- One-way binding to target -->
<Property Name="TotalOrders"
Value="{Binding Target.Dashboard.Orders, Mode=OneWayToSource}" />
</ServiceNode>Two-Way Binding
Data flows in both directions:
<ServiceNode Name="InventorySync">
<!-- Two-way binding for stock levels -->
<Property Name="StockLevels"
Value="{Binding Inventory.Stock, Mode=TwoWay}">
<Binding.UpdateTrigger>
<Trigger Path="/inventory/updated" />
<Trigger Path="/stock/changed" />
</Binding.UpdateTrigger>
</Property>
</ServiceNode>Value Converters
Data Conversion
Transform data during binding:
<ServiceNode Name="OrderNormalizer">
<ServiceNode.Resources>
<!-- Define converters -->
<Converter Name="PriceConverter">
<Convert From="string" To="decimal" />
</Converter>
<Converter Name="DateConverter">
<Convert From="string" To="datetime" />
</Converter>
</ServiceNode.Resources>
<!-- Use converters in bindings -->
<Property Name="OrderTotal"
Value="{Binding Order.Total,
Converter=PriceConverter}" />
<Property Name="OrderDate"
Value="{Binding Order.Date,
Converter=DateConverter}" />
</ServiceNode>Best Practices
-
Data Context
- Keep context focused
- Document inheritance
- Handle missing data
- Validate bindings
-
Binding Design
- Choose appropriate modes
- Use converters when needed
- Handle binding errors
- Monitor binding health
-
Performance
- Minimize binding chains
- Use appropriate update triggers
- Cache converted values
- Profile binding updates