![]() |
VOOZH | about |
dotnet add package OutWit.Common.Plugins --version 1.3.0
NuGet\Install-Package OutWit.Common.Plugins -Version 1.3.0
<PackageReference Include="OutWit.Common.Plugins" Version="1.3.0" />
<PackageVersion Include="OutWit.Common.Plugins" Version="1.3.0" />Directory.Packages.props
<PackageReference Include="OutWit.Common.Plugins" />Project file
paket add OutWit.Common.Plugins --version 1.3.0
#r "nuget: OutWit.Common.Plugins, 1.3.0"
#:package OutWit.Common.Plugins@1.3.0
#addin nuget:?package=OutWit.Common.Plugins&version=1.3.0Install as a Cake Addin
#tool nuget:?package=OutWit.Common.Plugins&version=1.3.0Install as a Cake Tool
See also: — end-to-end author & host guide covering NuGet packaging conventions (nuspec,
build/*.targets), module-folder layout, per-plugin config, and known issues. The README below documents the API surface only.
OutWit.Common.Plugins is a powerful and lightweight library for building extensible .NET applications. It provides a complete infrastructure for discovering, loading, and managing plugins with a strong focus on dependency resolution and lifecycle management.
The system allows for loading plugins into isolated AssemblyLoadContexts, which enables advanced features like unloading assemblies and hot-reloading plugins without restarting the main application.
*.dll).[WitPluginManifest]) and dependencies ([WitPluginDependency]).AssemblyLoadContext, preventing assembly conflicts and allowing plugins to be individually unloaded.Microsoft.Extensions.DependencyInjection. Plugins can register their own services and resolve dependencies from the host application or other plugins.Initialize, OnInitialized, OnUnloading).The solution is divided into two main projects:
OutWit.Common.Plugins.Abstractions: A lightweight package containing the interfaces (IWitPlugin) and attributes (WitPluginManifestAttribute, WitPluginDependencyAttribute) needed to create a plugin. Your plugin projects should reference this.OutWit.Common.Plugins: The main implementation containing the WitPluginLoader and all the logic for discovery, dependency resolution, and loading. Your host application should reference this.Install the necessary packages from NuGet.
For your plugin projects:
dotnet add package OutWit.Common.Plugins.Abstractions
For your host application:
Bash
dotnet add package OutWit.Common.Plugins
First, define a class that implements the
IWitPlugin interface (or inherits from the convenient WitPluginBase class ). Then, decorate it with the mandatory [WitPluginManifest] attribute.
// In MyAwesomePlugin.csproj
// <ProjectReference Include="..\OutWit.Common.Plugins.Abstractions.csproj" />
using OutWit.Common.Plugins.Abstractions;
using OutWit.Common.Plugins.Abstractions.Attributes;
using Microsoft.Extensions.DependencyInjection;
using System;
[WitPluginManifest("MyAwesomePlugin", Version = "1.1.0", Priority = 100)]
[WitPluginDependency("AnotherPlugin", MinimumVersion = "2.0.0")]
public class MyAwesomePlugin : WitPluginBase
{
// 1. Called first. Use this to register your services.
public override void Initialize(IServiceCollection services)
{
Console.WriteLine("MyAwesomePlugin: Initializing and registering services...");
services.AddSingleton<MyAwesomeService>();
}
// 2. Called after all plugins have been initialized and services are available.
public override void OnInitialized(IServiceProvider serviceProvider)
{
Console.WriteLine("MyAwesomePlugin: All plugins are loaded. Resolving services.");
var myService = serviceProvider.GetRequiredService<MyAwesomeService>();
myService.DoWork();
}
// 3. Called just before the plugin is unloaded.
public override void OnUnloading()
{
Console.WriteLine("MyAwesomePlugin: Unloading. Time for cleanup!");
}
}
// A sample service provided by this plugin
public class MyAwesomeService
{
public void DoWork() => Console.WriteLine("MyAwesomeService is doing work!");
}
In your host application, create an instance of the WitPluginLoader, load the plugins, and integrate them into your IServiceCollection.
using Microsoft.Extensions.DependencyInjection;
using OutWit.Common.Plugins;
using OutWit.Common.Plugins.Abstractions.Interfaces;
using System;
using System.IO;
public class Program
{
public static void Main(string[] args)
{
// Setup a directory for plugins
string pluginPath = Path.Combine(AppContext.BaseDirectory, "plugins");
Directory.CreateDirectory(pluginPath);
// (Ensure your plugin DLLs are copied to this directory)
var services = new ServiceCollection();
// 1. Initialize the plugin loader
// UseIsolatedContext defaults to true for hot-reloading capabilities
var loader = new WitPluginLoader<IWitPlugin>(pluginPath);
try
{
// 2. Discover metadata and resolve dependency order
loader.Load();
}
catch (AggregateException ex)
{
Console.WriteLine("Failed to load plugins:");
foreach (var inner in ex.InnerExceptions)
{
Console.WriteLine($"- {inner.Message}");
}
return;
}
// 3. Let each plugin register its services
foreach (var plugin in loader.Plugins)
{
plugin.Initialize(services);
}
// 4. Build the service provider
var serviceProvider = services.BuildServiceProvider();
// 5. Notify all plugins that initialization is complete
foreach (var plugin in loader.Plugins)
{
plugin.OnInitialized(serviceProvider);
}
Console.WriteLine("\nApplication is running. All plugins loaded.");
Console.WriteLine($"Loaded plugins by priority: {string.Join(", ", loader.Keys)}");
// ... your application logic ...
// 6. Unload a specific plugin (if using isolated contexts)
Console.WriteLine("\nAttempting to unload 'MyAwesomePlugin'...");
try
{
loader.UnloadPlugin("MyAwesomePlugin");
Console.WriteLine("Plugin unloaded successfully.");
}
catch(InvalidOperationException ex)
{
Console.WriteLine(ex.Message);
}
// 7. Dispose the loader to unload all remaining plugins
loader.Dispose();
Console.WriteLine("\nApplication shutting down. All plugins unloaded.");
}
}
Licensed under the Apache License, Version 2.0. See LICENSE.
If you use OutWit.Common.Plugins in a product, a mention is appreciated (but not required), for example: "Powered by OutWit.Common.Plugins (https://ratner.io/)".
"OutWit" and the OutWit logo are used to identify the official project by Dmitry Ratner.
You may:
You may not:
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 is compatible. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 is compatible. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 is compatible. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 2 NuGet packages that depend on OutWit.Common.Plugins:
| Package | Downloads |
|---|---|
|
OutWit.Engine.Sdk
Limited SDK version of WitEngine for controller plugin development and testing. Provides local execution with built-in limits for development workflows. |
|
|
OutWit.Shared.Storage.Providers
Blob-storage abstractions for OutWit hosts: IBlobStorageProvider (Write/Read/Delete by GUID+filename), IBlobStorageProviderPlugin (a marker over IWitPlugin so transports load via WitPluginLoader), IBlobStorageSettings (config contract), and MemoryPack-friendly BlobInfo / BlobUploadSession models. Drop-in for any backend — Disk / S3 / Azure Blob / GCS — via the plugin model. |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.3.0 | 105 | 5/27/2026 |
| 1.2.2 | 287 | 5/25/2026 |
| 1.2.1 | 98 | 5/24/2026 |
| 1.2.0 | 99 | 5/24/2026 |
| 1.1.7 | 666 | 5/18/2026 |
| 1.1.6 | 263 | 4/2/2026 |
| 1.1.5 | 225 | 3/7/2026 |
| 1.1.4 | 111 | 3/7/2026 |
| 1.1.3 | 114 | 3/5/2026 |
| 1.1.2 | 116 | 2/24/2026 |
| 1.1.1 | 146 | 1/25/2026 |
| 1.1.0 | 349 | 11/12/2025 |
| 1.0.2 | 165 | 9/6/2025 |
| 1.0.1 | 166 | 8/15/2025 |
| 1.0.0 | 124 | 8/1/2025 |