McBasic™Get McBasic™ ↗
Build 881
SDK implementation example

Observe the host lifecycle.

Read the full implementation before building the sample from the development checkout.

Complete component source#

LifecycleProbe.cs
using Avalonia.Controls;
using McBasic.ComponentSdk;

namespace McBasic.Samples.ComponentSdkLifecycle;

[McComponent(
    "com.mcbasic.samples.componentlifecycle.LifecycleProbe",
    "LifecycleProbe",
    "Lifecycle Probe",
    ApiVersion = McComponentSdkContract.CurrentApiVersion,
    Category = "SDK Samples",
    Description = "Records the public generated-app lifecycle and resource boundary.",
    DefaultWidth = 280,
    DefaultHeight = 96)]
public sealed class LifecycleProbe : Border, IMcComponentLifecycle, IDisposable
{
    private CancellationToken lifetime;
    private CancellationTokenRegistration cancellationRegistration;
    private bool initialized;
    private bool active;
    private bool disposed;

    public void Initialize(IMcComponentContext context)
    {
        ArgumentNullException.ThrowIfNull(context);
        if (initialized || disposed) throw new InvalidOperationException("Initialize must run exactly once.");
        initialized = true;
        lifetime = context.Lifetime;
        var missingRejected = !context.Resources.Contains("MissingResource");
        try
        {
            using var unused = context.Resources.OpenRead("MissingResource");
            missingRejected = false;
        }
        catch
        {
            // This sample intentionally probes the missing-resource boundary.
        }
        cancellationRegistration = lifetime.Register(
            () => Console.WriteLine("SDK-LIFECYCLE cancelled"));
        Console.WriteLine($"SDK-LIFECYCLE initialize resources={context.Resources.Names.Count} missingRejected={missingRejected}");
    }

    public void Activate()
    {
        if (!initialized || disposed || active) throw new InvalidOperationException("Activate order is invalid.");
        active = true;
        Console.WriteLine("SDK-LIFECYCLE activate");
    }

    public void Deactivate()
    {
        if (!active || disposed || !lifetime.IsCancellationRequested)
            throw new InvalidOperationException("Deactivate requires an active component with cancelled lifetime.");
        active = false;
        Console.WriteLine("SDK-LIFECYCLE deactivate lifetimeCancelled=True");
    }

    public void Dispose()
    {
        if (disposed) throw new InvalidOperationException("Dispose must run exactly once.");
        disposed = true;
        cancellationRegistration.Dispose();
        if (active || !lifetime.IsCancellationRequested)
            throw new InvalidOperationException("Dispose requires completed cancellation and deactivation.");
        Console.WriteLine("SDK-LIFECYCLE dispose");
    }
}

Project configuration#

ComponentSdkLifecycle.csproj
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="../../src/McBasic.ComponentSdk/McBasic.ComponentSdk.csproj" Private="false" />
    <PackageReference Include="Avalonia" />
  </ItemGroup>
</Project>

Follow the compile, package and runtime-check walkthrough.

Source baseline 20f4bfed6b · Build manifest