Skip to content

v0.2.2 Changelog

Release date: February 27, 2026

v0.2.2 is a feature release in the v0.2.x line, containing one breaking change (plugin directory rename) and one new feature (plugin-specific data directory support).

Breaking Changes

Plugin directory renamed: Plugins/plugins/

The directory scanned by the host for plugin DLLs has been renamed from Plugins to plugins (lowercase initial letter) to follow cross-platform naming conventions.

EnvironmentImpact
Linux / macOS⚠️ Affected: you must manually rename the existing Plugins/ directory to plugins/, otherwise all plugins will fail to load after the upgrade
Windows✅ Not affected: the file system is case-insensitive, no action required

For step-by-step migration instructions, see the User-side Migration Guide.

New Features

New: Plugin-specific Data Directory (DataDirectory and GetDataPath)

Plugins can now access a dedicated data directory through two new interface members, suitable for storing databases, key pairs, caches, exported files, and other persistent data.

DataDirectory Property

Returns the full path to the plugin's dedicated data directory. Defaults to {BaseDir}/data/{PluginName}/.

csharp
// Default implementation
string DataDirectory => Path.Combine(AppContext.BaseDirectory, "data", Name);

TIP

DataDirectory is intended to be used as a read-only property and should not be overridden. For a standardized and predictable plugin ecosystem, all persistent files produced by a plugin should always reside within the plugin's dedicated data directory.

GetDataPath(string relativePath) Method

A path-combining helper for DataDirectory, supporting both relative and absolute paths:

csharp
// Relative path → {DataDirectory}/keys/private.pem
var keyPath = GetDataPath("keys/private.pem");

// Absolute path → returned as-is; DataDirectory is ignored
var keyPath = GetDataPath("/mnt/hsm/private.pem");

The absolute path passthrough behavior follows the native rules of Path.Combine. This allows users to configure an absolute path in the plugin's config file to redirect storage to any location outside the data directory (e.g., an HSM mount point).

Automatic Directory Creation

The host automatically ensures the directory pointed to by DataDirectory exists before plugin services are registered. Plugins do not need to call Directory.CreateDirectory manually.

Example directory structure after startup:

{BaseDir}/
├── config/
│   └── my.plugin.json
└── data/
    └── my.plugin/          ← created automatically by the host
        ├── plugin.db
        └── keys/
            └── private.pem

Usage With Plugin Configuration

The recommended pattern is to set path fields to relative path strings in DefaultConfig. The host writes them to the config file on first run. In RegisterServices, use GetDataPath to resolve them to absolute paths at runtime. All persistent files produced by a plugin should always reside within the plugin's dedicated data directory.

csharp
public object? DefaultConfig => new MySettings
{
    // ✅ Recommended: store relative paths in DefaultConfig
    PrivateKeyPath = "keys/private.pem",
    DatabasePath   = "data.db"
};

public void RegisterServices(IServiceCollection services, IConfiguration configuration)
{
    var settings = configuration.Get<MySettings>()!;

    // GetDataPath resolves the relative path to an absolute path:
    // "data.db"          → {DataDirectory}/data.db
    // "keys/private.pem" → {DataDirectory}/keys/private.pem
    var resolvedKeyPath = GetDataPath(settings.PrivateKeyPath);

    if (!File.Exists(resolvedKeyPath))
        GenerateKeyPair(resolvedKeyPath);

    services.Configure<MySettings>(configuration);
}

Compatibility

  • Both new members have default implementations — existing plugins require no code changes and will compile as-is
  • NuGet references using Version="0.2.*" will automatically resolve to this version
  • The host must be updated to v0.2.2 to gain automatic data directory creation; updating only the contracts library has no effect on existing behavior