SkiaComponentRegistry is a static catalog of component types. It is the single source of truth that the palette, templates, serialization and palette drops all read from. It stores no instances — only AssemblyClassDefinition metadata and factory helpers.

What It Stores

The registry keeps a List<AssemblyClassDefinition> (exposed as LoadedComponents). Each entry describes one component type:

MemberTypeMeaning
classNamestringClass name; the palette converts it to a display label.
dllnamestringAssembly that provides the type.
GuidIDstringStable identifier for lookups.
typeTypeResolved CLR type used for instantiation.
MethodsList<MethodsClass>Optional command methods surfaced as palette children.

Duplicates are rejected on insert by comparing GuidID, or className plus dllname. Re-registering the same type is therefore a no-op rather than an error.

Registration

Three shapes are available depending on how many entries you have:

// One at a time
SkiaComponentRegistry.AddComponent(definition);

// A batch (skips duplicates individually)
SkiaComponentRegistry.AddComponents(definitions);

// Replace everything (used when re-scanning a plugin folder)
SkiaComponentRegistry.SetComponents(definitions);

In practice you rarely call these directly. The supported paths are:

  • Extension SDK — ISkiaExtension.GetComponentTypes() declares types and ISkiaExtensionContext.RegisterComponent(type, category, displayName) registers them; SkiaExtensionHost performs discovery. See Extension SDK.
  • Assembly scanning — hosts that already use the shared BeepDM AssemblyHandler feed the discovered definitions into SetComponents/AddComponents.
  • Tests and tools — construct AssemblyClassDefinition values directly and call Clear() between runs.

Queries

MemberReturns
GetComponents()All registered definitions.
GetComponentsOrdered()The same list ordered for display; the palette uses this.
GetComponentByName(className)The definition for a class name, or null.
GetComponentByGuid(guid)The definition for a stable id, or null.
GetComponentsByAssembly(assemblyName)Everything provided by one assembly.
GetComponentsByType(typeName)Everything matching a type name.
GetComponentsWithMethods()Only components that expose command methods.
GetComponentsWithVisualProperties()Components that carry designer/visual metadata.
GetComponentsByCapabilities(hasLocalDB, isDataSource, inMemory)Capability-filtered subsets.
GetAvailableNamespaces()Distinct namespaces, useful for grouping in tools.
IsComponentRegistered(className)Fast existence check.
Clear()Empties the registry (tests, host shutdown).

Instantiation

Two overloads create instances: from a definition or from a class name. Both use the parameterless constructor, so every component type must have one.

// From a palette item (ComponentItem wraps the definition)
var component = SkiaComponentRegistry.CreateComponentInstance(args.Component.ClassDefinition);

// From a name
var node = SkiaComponentRegistry.CreateComponentInstance("ProcessNode");

if (node != null)
{
    node.X = 120;
    node.Y = 80;
    drawingManager.AddComponent(node);
}

Creation is deliberately dumb: it constructs the type and returns it. Positioning, naming, undo registration and parenting belong to the caller (the host control does all four when you drop from the palette).

Who Reads It

ConsumerUsage
ComponentPaletteLoadComponentsFromRegistry() groups GetComponentsOrdered() into categories.
DrawingManager templatesGetTemplates() and LoadTemplate(dto) build diagrams from built-in DTOs.
SerializationLoadFromDto resolves ComponentDto.Type with Type.GetType(); a missing type is skipped, not fatal.
Extension hostRegisters extension components and commands during Initialize.
TestsWhole-surface sweeps enumerate the registry to exercise every component type.

Registry vs. Extension SDK

The registry is storage; the extension SDK is the supported way to fill it. Prefer implementing ISkiaExtension over calling AddComponent directly so packages can be installed, versioned and uninstalled through the marketplace.