SDK contracts and attributes
The full SDK 1.0 public contract, with identity, metadata, lifecycle and resource ownership explained.
Assembly and schema identity#
| Constant | Current value | Meaning |
|---|---|---|
| AssemblyName | McBasic.ComponentSdk | The shared contract assembly identity. |
| CurrentApiVersion | 1.0 | Host/component API agreement, independent of package version. |
| PackageSchemaVersion | 1 | Version of the package manifest shape. |
| ApiMetadataSchemaVersion | 1 | Version of static component API metadata. |
Reference the shared SDK assembly. Do not embed a private renamed copy and expect the host to recognize its interfaces or attributes.
McComponentAttribute#
Place this attribute on the public C# component class. Its three constructor arguments are stable component ID, BASIC type name and display name, in that order.
| Member | Type / default | Use |
|---|---|---|
| Id | String · constructor | Globally qualified stable component identity. |
| BasicName | String · constructor | The type name exposed to BASIC. |
| DisplayName | String · constructor | Human-readable Toolbox name. |
| Category | String · Custom Controls | Toolbox grouping. |
| ApiVersion | String · 1.0 | The supported SDK contract. |
| NonVisual | Boolean · False | Whether an instance has no visual surface. |
| Container | Boolean · False | Whether it accepts visual children. |
| Description | String · empty | Explain the purpose of the component. |
| Icon | String? · null | Package-relative icon file. |
| Documentation | String? · null | Package-relative documentation file. |
| DefaultWidth | Double · 160 | Initial width in device-independent points. |
| DefaultHeight | Double · 32 | Initial height in device-independent points. |
| Resizable | Boolean · True | Whether the Designer permits resizing. |
McPropertyAttribute#
Apply to a public property. The parameterless constructor exports its CLR name; the String constructor supplies a BASIC name override.
| Member | Type / default | Use |
|---|---|---|
| Name | String? · constructor | Optional exported name. |
| Description | String · empty | Help text for Inspector and browsing. |
| ReadOnly | Boolean · False | Disallow authored assignment. |
| DefaultValueJson | String? · null | Default value encoded as JSON, not as an arbitrary C# expression. |
| ResetValueJson | String? · null | Reset value encoded as JSON. |
| Editor | String? · null | A registered editor identifier; the current schema allows Text. |
An absent default is not the same as zero or an empty string. Keep metadata defaults consistent with the runtime property behavior and use a type the exporter can represent.
McMethodAttribute and McEventAttribute#
| Attribute | Members | Purpose |
|---|---|---|
| McMethod | Name (optional constructor override), Description, Async (False by default) | Export a public method and identify the supported asynchronous contract when applicable. |
| McEvent | Name (optional constructor override), Description | Export a public event with its typed parameter contract. |
The exporter determines signatures from supported public members. Document every parameter’s type and direction. Do not invent a method overload in a guide that the exported metadata does not contain.
IMcComponentContext#
| Member | Type | Responsibility |
|---|---|---|
| Resources | IMcComponentResourceProvider | Read-only access to declared logical resources. |
| Lifetime | CancellationToken | Signals owner teardown; stop background work. |
The context is instance-scoped. It does not hand a component the IDE, arbitrary filesystem paths or process-global services. Additional host services are not implied by implementing this interface.
IMcComponentResourceProvider#
| Member | Result | Ownership |
|---|---|---|
| Names | IReadOnlyCollection<String> | Declared logical names in deterministic order. |
| Contains(logicalName) | Boolean | Test whether a resource is declared. |
| OpenRead(logicalName) | Stream | A bounded read-only stream. The caller closes it. |
A logical resource name is not a path. Ask for a declared name, handle a missing resource and dispose the returned stream. Do not reinterpret a user-supplied logical name as an arbitrary file location.
IMcComponentLifecycle#
| Callback | When | What to do |
|---|---|---|
| Initialize(context) | Before authored properties are applied | Capture the instance context and prepare owned state. |
| Activate() | After Form initialization | Start work that needs an initialized visual tree. |
| Deactivate() | After Lifetime has been cancelled | Stop activity and release active subscriptions. |
| IDisposable.Dispose(), if implemented | After deactivation during teardown | Release remaining owned resources. |
The host calls each lifecycle method at most once on the UI dispatcher. Cancellation precedes Deactivate. Do not call these methods yourself from the consumer or assume the component can keep updating a closed Form.
Exact contract source#
The following is the actual SDK contract source for this documentation snapshot. It is an API definition, not a copied manual chapter.
using System.IO;
namespace McBasic.ComponentSdk;
/// <summary>Stable identifiers for the McBasic Component SDK contract.</summary>
public static class McComponentSdkContract
{
/// <summary>The one shared contract assembly identity.</summary>
public const string AssemblyName = "McBasic.ComponentSdk";
/// <summary>The Component SDK contract version accepted by this toolchain.</summary>
public const string CurrentApiVersion = "1.0";
/// <summary>The package manifest schema emitted by this toolchain.</summary>
public const int PackageSchemaVersion = 1;
/// <summary>The static API metadata schema emitted by this toolchain.</summary>
public const int ApiMetadataSchemaVersion = 1;
}
/// <summary>
/// Provides read-only access to resources declared by the consuming McBasic
/// project. Logical names are not filesystem paths. The caller owns streams
/// returned by <see cref="OpenRead"/>.
/// </summary>
public interface IMcComponentResourceProvider
{
/// <summary>Gets declared logical names in deterministic order.</summary>
IReadOnlyCollection<string> Names { get; }
/// <summary>Returns whether a declared logical resource exists.</summary>
bool Contains(string logicalName);
/// <summary>Opens a bounded read-only stream. The caller owns the stream.</summary>
Stream OpenRead(string logicalName);
}
/// <summary>
/// Host-owned services and lifetime state supplied to one component instance.
/// The context exposes no IDE objects, filesystem paths or process-global
/// services. Additional services can be added as optional interfaces in later
/// compatible SDK revisions.
/// </summary>
public interface IMcComponentContext
{
/// <summary>Gets bounded read-only access to resources declared by the consuming project.</summary>
IMcComponentResourceProvider Resources { get; }
/// <summary>Signals that the owning Form is unloading and component work must stop.</summary>
CancellationToken Lifetime { get; }
}
/// <summary>
/// Optional generated-app lifecycle implemented by a visual component. The
/// host calls each method at most once and always on the UI dispatcher.
/// Initialize precedes authored property application; Activate follows Form
/// initialization. During teardown Lifetime is cancelled before Deactivate,
/// followed by ordinary <see cref="IDisposable.Dispose"/> when implemented.
/// </summary>
public interface IMcComponentLifecycle
{
/// <summary>Receives the instance-scoped host context before property application.</summary>
void Initialize(IMcComponentContext context);
/// <summary>Starts work after the visual tree and owning Form are initialized.</summary>
void Activate();
/// <summary>Stops work during deterministic Form teardown.</summary>
void Deactivate();
}Complete attribute declarations
namespace McBasic.ComponentSdk;
/// <summary>Declares a public C# control that can be packaged for McBasic.</summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class McComponentAttribute : Attribute
{
/// <summary>Declares stable component, BASIC and display identities.</summary>
public McComponentAttribute(string id, string basicName, string displayName)
{
Id = id;
BasicName = basicName;
DisplayName = displayName;
}
/// <summary>Gets the globally qualified stable component identifier.</summary>
public string Id { get; }
/// <summary>Gets the type name exposed to BASIC.</summary>
public string BasicName { get; }
/// <summary>Gets the user-facing component name.</summary>
public string DisplayName { get; }
/// <summary>Gets or sets the Toolbox category.</summary>
public string Category { get; set; } = "Custom Controls";
/// <summary>The McBasic Component SDK contract version, not the package version.</summary>
public string ApiVersion { get; set; } = McComponentSdkContract.CurrentApiVersion;
/// <summary>Gets or sets whether the component has no visual surface.</summary>
public bool NonVisual { get; set; }
/// <summary>Gets or sets whether the component accepts McBasic visual children.</summary>
public bool Container { get; set; }
/// <summary>Gets or sets the help summary.</summary>
public string Description { get; set; } = "";
/// <summary>Optional package-relative icon path used by the metadata-only Toolbox.</summary>
public string? Icon { get; set; }
/// <summary>Optional package-relative documentation path used by help and signature UI.</summary>
public string? Documentation { get; set; }
/// <summary>Gets or sets the default design width in device-independent pixels.</summary>
public double DefaultWidth { get; set; } = 160;
/// <summary>Gets or sets the default design height in device-independent pixels.</summary>
public double DefaultHeight { get; set; } = 32;
/// <summary>Gets or sets whether the designer permits interactive resizing.</summary>
public bool Resizable { get; set; } = true;
}
/// <summary>Exports a public C# property to the McBasic inspector.</summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class McPropertyAttribute : Attribute
{
/// <summary>Exports the CLR property using its CLR name.</summary>
public McPropertyAttribute() { }
/// <summary>Exports the CLR property using the specified BASIC name.</summary>
public McPropertyAttribute(string name) => Name = name;
/// <summary>Gets the optional BASIC name override.</summary>
public string? Name { get; }
/// <summary>Gets or sets the Inspector and Object Browser help text.</summary>
public string Description { get; set; } = "";
/// <summary>Gets or sets whether authored assignment is forbidden.</summary>
public bool ReadOnly { get; set; }
/// <summary>Gets or sets the default value encoded as JSON.</summary>
public string? DefaultValueJson { get; set; }
/// <summary>Gets or sets the reset value encoded as JSON.</summary>
public string? ResetValueJson { get; set; }
/// <summary>Gets or sets a registered SDK property-editor identifier.</summary>
public string? Editor { get; set; }
}
/// <summary>Exports a public C# method to McBasic signature help.</summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class McMethodAttribute : Attribute
{
/// <summary>Exports the CLR method using its CLR name.</summary>
public McMethodAttribute() { }
/// <summary>Exports the CLR method using the specified BASIC name.</summary>
public McMethodAttribute(string name) => Name = name;
/// <summary>Gets the optional BASIC name override.</summary>
public string? Name { get; }
/// <summary>Gets or sets signature-help and Object Browser text.</summary>
public string Description { get; set; } = "";
/// <summary>Gets or sets whether the method uses the SDK async contract.</summary>
public bool Async { get; set; }
}
/// <summary>Exports a public C# event to the McBasic event list.</summary>
[AttributeUsage(AttributeTargets.Event, AllowMultiple = false, Inherited = true)]
public sealed class McEventAttribute : Attribute
{
/// <summary>Exports the CLR event using its CLR name.</summary>
public McEventAttribute() { }
/// <summary>Exports the CLR event using the specified BASIC name.</summary>
public McEventAttribute(string name) => Name = name;
/// <summary>Gets the optional BASIC name override.</summary>
public string? Name { get; }
/// <summary>Gets or sets event-editor and Object Browser text.</summary>
public string Description { get; set; } = "";
}20f4bfed6b · Build manifest