97 lines
5.0 KiB
Markdown
97 lines
5.0 KiB
Markdown
# AddonLib
|
||
|
||
AddonLib
|
||
|
||
Overview
|
||
- AddonLib is a .NET 8 library for building addon-enabled applications in C#.
|
||
- It lets app developers expose a host API to addons and raise callbacks; addon developers implement addons that react to callbacks and call back into the host.
|
||
|
||
Projects
|
||
- AddonLib: core library containing attributes, base classes, and AddonManager.
|
||
- HostApp: example host application that integrates AddonLib and auto-loads plugins from a Plugins folder.
|
||
- SampleAddon: example addon implementing AddonBase and reacting to host callbacks.
|
||
|
||
Key concepts
|
||
- Assembly-level addon metadata: [assembly: Addon(name, author, version)]
|
||
- Addon base class: inherit from AddonBase to access Context, Services, and host helper methods.
|
||
- Callbacks: mark methods with [AddonCallback("EventName")] (or omit the name to use the method name). The host raises these events so addons receive notifications.
|
||
- Host API exposure:
|
||
- Methods: mark host methods with [AddonCallable("Name?")] so addons can call them via CallHost.
|
||
- Fields/Properties: mark with [AddonAccessible(ReadOnly|ReadWrite, "Name?")] so addons can GetHostValue/SetHostValue.
|
||
|
||
Auto plugin loading
|
||
- AddonManager can auto-create a Plugins directory and auto-load all addon DLLs from it at startup.
|
||
- Default directory is AppContext.BaseDirectory/Plugins (configurable via constructor).
|
||
|
||
Host quick start
|
||
1) Create and configure the manager in your app entry point:
|
||
- `var manager = new AddonManager("Plugins", autoInitialize: true);`
|
||
2) Register an API object with attributes for addons to call and access:
|
||
- `manager.RegisterHostApi(new HostApi(manager));`
|
||
3) Raise callbacks from host code so addons can react:
|
||
- Mark a host method with [AddonCallback] and inside it call `manager.RaiseAddonCallback()` (uses the caller method name as event), or
|
||
- Call `manager.RaiseCallback(MethodBase.GetCurrentMethod(), args...)` to use an explicit [AddonCallback("EventName")] annotation.
|
||
|
||
Addon quick start
|
||
1) Mark the assembly with metadata:
|
||
- `[assembly: Addon("My Addon", "Me", "1.0.0")]`
|
||
2) Create a class inheriting AddonBase:
|
||
- `public sealed class MyAddon : AddonBase { ... }`
|
||
3) Add callback methods annotated with [AddonCallback]:
|
||
- `[AddonCallback] void OnTick(AddonContext ctx) { var message = CallHost("Echo", "Hi"); }`
|
||
4) Optional: use GetHostValue/SetHostValue for members marked [AddonAccessible].
|
||
5) Build the addon and drop the resulting DLL into the host Plugins folder.
|
||
|
||
Examples in this repository
|
||
- HostApp demonstrates:
|
||
- Initializing AddonManager with auto-initialization and autoload.
|
||
- Registering a HostApi with [AddonCallable], [AddonAccessible], and [AddonCallback].
|
||
- Raising callbacks using `manager.RaiseAddonCallback()`.
|
||
- SampleAddon demonstrates:
|
||
- Declaring addon metadata.
|
||
- Subscribing to the host OnTick event with [AddonCallback] and using CallHost/GetHostValue/SetHostValue.
|
||
|
||
Attributes reference (summary)
|
||
- AddonAttribute (assembly): Addon(name, author, version)
|
||
- AddonCallbackAttribute (method): optional EventName; if omitted, method name is used. AllowMultiple = true to bind one method to multiple events.
|
||
- AddonCallableAttribute (method): optional Name; if omitted, method name is used. Host methods callable by addons.
|
||
- AddonAccessibleAttribute (field/property): access mode ReadOnly or ReadWrite and optional Name; if omitted, member name is used.
|
||
|
||
AddonBase essentials
|
||
- Context: Addon metadata and assembly.
|
||
- Services: optional IServiceProvider provided by the host.
|
||
- CallHost(name, params object?[] args)
|
||
- GetHostValue(name)
|
||
- SetHostValue(name, value)
|
||
- Lifecycle: OnLoaded(), OnUnloading()
|
||
|
||
AddonManager essentials
|
||
- Constructors:
|
||
- AddonManager() – no auto init
|
||
- AddonManager(string? pluginsDirectory, bool autoInitialize = true, IServiceProvider? services = null)
|
||
- Properties: PluginsDirectory, LoadedAddons
|
||
- API exposure: RegisterHostApi(object host)
|
||
- Loading:
|
||
- InitializePluginsDirectory(createIfMissing = true)
|
||
- LoadAllFromPluginsDirectory(SearchOption.TopDirectoryOnly)
|
||
- LoadFrom(string assemblyPath)
|
||
- LoadFrom(Assembly assembly)
|
||
- Callbacks:
|
||
- RaiseCallback(string eventName, params object?[] args)
|
||
- RaiseCallback(MethodBase method, params object?[] args)
|
||
- Extensions: manager.RaiseAddonCallback() (uses caller member name), manager.RaiseAddonCallbackFrom(MethodBase, ...)
|
||
|
||
Common convenience behaviors
|
||
- [AddonCallback] without a name uses the method name as the event name.
|
||
- Callback parameter injection supports AddonContext, IServiceProvider (when compatible), and AddonManager automatically.
|
||
- RegisterHostApi also scans static methods/fields/properties for attributes on the provided type for convenience.
|
||
|
||
Build and run (example)
|
||
- Build SampleAddon
|
||
- Copy SampleAddon/bin/Debug/net8.0/SampleAddon.dll to HostApp/Plugins
|
||
- Build and run HostApp
|
||
- Press T to raise the OnTick event; see SampleAddon reacting in the console.
|
||
|
||
Notes
|
||
- Only assemblies that include [assembly: Addon(...)] and contain a non-abstract AddonBase implementation are loaded as addons.
|
||
- Non-addon DLLs in the Plugins directory are ignored. |