Skip to content

v0.2.0 Changelog

Release date: February 26, 2026

v0.2.0 is the first major architectural upgrade of SharwAPI. This release includes a full refactor of the host, introduces a plugin dependency management system, and significantly expands the IApiPlugin interface.

Upgrade Notice

v0.2.0 contains breaking changes. Plugins may not work correctly after a simple binary replacement. Please read the Migration Guide before upgrading.

Changes for Users

Logging System Overhaul

The previous logging system only wrote to the console during startup and lacked persistence. v0.2.0 introduces Serilog as the unified logging framework:

  • Logs are written to both the console and files simultaneously
  • Log files roll daily, retaining the last 30 days by default, with a maximum of 10 MB per file
  • Log file path: logs/log-{date}.txt

This affects the logging configuration section in appsettings.json. See the User Migration Guide for details.

Per-Plugin Configuration Files

Previously, all plugins could only read from the main appsettings.json. Now each plugin has its own dedicated configuration file:

  • Path: config/{PluginName}.json (in the application working directory)
  • On first startup, if a plugin provides a default config, the system automatically creates this file

This means you can modify a single plugin's configuration without worrying about affecting other plugins or the host.

Configurable Route Prefixes

A new RouteOverride configuration section allows overriding a plugin's route prefix without modifying plugin code:

json
{
  "RouteOverride": {
    "my.plugin": "custom-path"
  }
}

This changes my.plugin's route prefix from /my.plugin/... to /custom-path/....

Only applies to plugins that have enabled UseAutoRoutePrefix.

Host Architecture Refactored

The host has been refactored from a single Program.cs into a modular structure, with startup logic split into dedicated modules:

ModuleResponsibility
ApplicationHostApplication assembly and startup
PluginLoaderPlugin discovery and loading
PluginDependencyCheckerDependency checking and topological sort
PluginServiceRegistrarService registration
EndpointRegistrationRoute registration
RoutePrefixResolverRoute prefix resolution

This refactor does not affect normal usage; the startup method and configuration format (after upgrading) remain compatible.

Plugin Isolation Loading

Plugins are now loaded through an isolated AssemblyLoadContext, preventing version conflicts between plugins that depend on different versions of the same third-party library.

Upgrade to .NET 10 and Self-Contained Deployment

The host and sharwapi.Contracts.Core have been upgraded from .NET 9 to .NET 10. The host is now published as a self-contained binary:

  • No .NET runtime required: The .NET 10 runtime is bundled with the host executable — just run it directly on the target machine
  • Larger package size: Self-contained packages include the full runtime and are larger than framework-dependent builds
  • Runtime isolation: Not affected by other .NET versions installed on the target machine

Changes for Plugin Developers

New: Plugin Dependency Declaration (Dependencies)

Plugins can now declare dependencies on other plugins:

csharp
public IReadOnlyDictionary<string, string> Dependencies => new Dictionary<string, string>
{
    { "CorePlugin", "[1.0,2.0)" }
};

The system automatically checks dependencies at startup. Plugins with unmet dependencies are skipped and a warning is logged. Version range format follows NuGet conventions (e.g., 1.0, [1.0,2.0), *).

New: Custom Dependency Validation (ValidateDependency())

In addition to declarative dependency checking, plugins can implement this method for more complex runtime dependency logic:

csharp
public bool ValidateDependency(IReadOnlyDictionary<string, string> loadedPluginVersions)
{
    // Return false to prevent this plugin from loading
    return loadedPluginVersions.ContainsKey("RequiredPlugin");
}

The default implementation returns true (no additional validation).

New: Automatic Route Prefix (UseAutoRoutePrefix)

When enabled, routes registered by the plugin automatically receive a /{PluginName}/ prefix:

csharp
public bool UseAutoRoutePrefix => true;

The prefix can be overridden via the RouteOverride section in appsettings.json.

New: Default Configuration Object (DefaultConfig)

Plugins can provide a default configuration object that is automatically generated as a file when the config file doesn't exist:

csharp
public object? DefaultConfig => new MyPluginSettings
{
    Port = 8080,
    Enabled = true
};

Breaking Change: configuration Parameter Semantics in RegisterServices() and RegisterRoutes()

This is one of the most important changes in this upgrade.

  • v0.1.0: Both methods received the global appsettings.json configuration
  • v0.2.0: Both methods now receive the plugin-specific config/{PluginName}.json configuration

If your plugin reads custom sections from appsettings.json in either method, you'll need to move that configuration to the plugin-specific config file and provide defaults via DefaultConfig.

See the Developer Migration Guide for details.

Breaking Change: Target Framework Upgraded to .NET 10

sharwapi.Contracts.Core now targets net10.0. Plugin projects must update their target framework from net9.0 to net10.0 to reference the new version of the Contracts package. This is one of the breaking changes for plugin developers in this upgrade and requires recompilation.

See the Developer Migration Guide for details.

Breaking Change: Switch to NuGet Package Reference

sharwapi.Contracts.Core is now distributed via a private NuGet feed. Plugin projects must replace the ProjectReference to sharwapi.Contracts.Core with a PackageReference and add the private feed to nuget.config. This is one of the breaking changes for plugin developers in this upgrade.

See the Developer Migration Guide for details.