Overview
ComponentBinding represents a mapping between server-side types and client-side UI components. It implements the IComponentBinding interface and is used by the metadata binder to determine which component should be used to render a specific type.
Namespace
UiMetadataFramework.Core.Binding
Interfaces
Properties
Component category to which this component belongs. Components within the same category must have unique names. Common categories include "input" and "output" (see MetadataBinder.ComponentCategories).
Name of the client-side component that will be rendered. This corresponds to the component name on the client.
Collection of server-side types that are mapped to this component. Multiple types can be bound to the same component.
Type of the IMetadataFactory to use for constructing component metadata. If null, DefaultMetadataFactory will be used.
AllowedConfigurations
HasConfigurationAttribute[]
Array of allowed configurations for this component. Configurations customize component behavior and appearance.
AdditionalData
IReadOnlyDictionary<string, object?>?
Additional data associated with this component type. Can be used to pass custom metadata to the client.
Constructors
Single Server Type Constructor
public ComponentBinding(
string category,
Type serverType,
string componentType,
Type? metadataFactory,
params HasConfigurationAttribute[] allowedConfigurations)
Creates a binding for a single server type.
Component category (e.g., “input” or “output”).
Server-side type to bind to the component.
Name of the client-side component.
Metadata factory type, or null to use the default.
allowedConfigurations
HasConfigurationAttribute[]
Allowed configurations for the component.
Multiple Server Types Constructor
public ComponentBinding(
string category,
IEnumerable<Type> serverTypes,
ComponentAttribute attribute,
params HasConfigurationAttribute[] allowedConfigurations)
Creates a binding for multiple server types using a component attribute.
Collection of server-side types to bind to the component.
Component attribute containing component configuration.
allowedConfigurations
HasConfigurationAttribute[]
Allowed configurations for the component.
Methods
GetAdditionalData<T>
public T? GetAdditionalData<T>(string key)
Attempts to retrieve a value from AdditionalData with the specified key and of the specified type.
Key of the item in AdditionalData.
Type that the value should have. If the value exists but is not of this type, the default value will be returned.
Returns: Value from AdditionalData or default if no matching value was found.
Equals
public override bool Equals(object? obj)
Determines whether two component bindings are equal based on their category, component type, and server types.
GetHashCode
public override int GetHashCode()
Returns a hash code for the component binding.
Usage Examples
Creating a Simple Component Binding
var binding = new ComponentBinding(
category: MetadataBinder.ComponentCategories.Input,
serverType: typeof(string),
componentType: "text",
metadataFactory: null
);
Creating a Binding with Multiple Server Types
var binding = new ComponentBinding(
category: MetadataBinder.ComponentCategories.Input,
serverTypes: new[] { typeof(int), typeof(long), typeof(decimal) },
componentType: "number",
metadataFactory: typeof(NumberMetadataFactory)
);
Creating a Binding with Configurations
public class MaxLengthConfiguration : HasConfigurationAttribute
{
public int MaxLength { get; set; }
}
public class MinLengthConfiguration : HasConfigurationAttribute
{
public int MinLength { get; set; }
}
var binding = new ComponentBinding(
category: MetadataBinder.ComponentCategories.Input,
serverType: typeof(string),
componentType: "text",
metadataFactory: null,
allowedConfigurations: new HasConfigurationAttribute[]
{
new MaxLengthConfiguration(),
new MinLengthConfiguration()
}
);
public class CustomComponentBinding : ComponentBinding
{
public CustomComponentBinding()
: base(
category: MetadataBinder.ComponentCategories.Input,
serverType: typeof(CustomType),
componentType: "custom-input",
metadataFactory: typeof(CustomMetadataFactory))
{
}
}
// Register the binding
var binder = new MetadataBinder();
binder.RegisterAssembly(typeof(CustomComponentBinding).Assembly);
Accessing Additional Data
public class RichComponentBinding : ComponentBinding
{
public RichComponentBinding()
: base(
category: MetadataBinder.ComponentCategories.Output,
serverTypes: new[] { typeof(RichContent) },
attribute: new ComponentAttribute("rich-editor")
{
// Additional data can be set via the attribute
})
{
// Set additional data
AdditionalData = new Dictionary<string, object?>
{
["syntax-highlighting"] = true,
["theme"] = "dark",
["plugins"] = new[] { "spellcheck", "wordcount" }
};
}
}
// Later, retrieve the data
var syntaxHighlighting = binding.GetAdditionalData<bool>("syntax-highlighting");
var theme = binding.GetAdditionalData<string>("theme");
var plugins = binding.GetAdditionalData<string[]>("plugins");
Custom Component Binding Class
public class DateRangeInputBinding : ComponentBinding
{
public DateRangeInputBinding()
: base(
category: MetadataBinder.ComponentCategories.Input,
serverType: typeof(DateRange),
componentType: "date-range",
metadataFactory: typeof(DateRangeMetadataFactory),
allowedConfigurations: new HasConfigurationAttribute[]
{
new MinDateConfiguration(),
new MaxDateConfiguration()
})
{
}
}
public class DateRange
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
IComponentBinding Interface
The IComponentBinding interface defines the contract that all component bindings must implement:
public interface IComponentBinding
{
IReadOnlyDictionary<string, object?>? AdditionalData { get; }
HasConfigurationAttribute[] AllowedConfigurations { get; }
string ComponentType { get; }
Type? MetadataFactory { get; }
IEnumerable<Type> ServerTypes { get; }
}
Notes
- Component bindings are typically created by inheriting from
ComponentBinding and registering them with the MetadataBinder.
- Multiple server types can be mapped to the same component, allowing for type consolidation on the client side.
- The
MetadataFactory property allows for custom metadata generation logic.
- Additional data can be used to pass component-specific configuration to the client.
- Component bindings are automatically discovered and registered when calling
MetadataBinder.RegisterAssembly().
See Also