626 lines
28 KiB
Markdown
626 lines
28 KiB
Markdown
# Plugin Architecture
|
||
|
||
<cite>
|
||
**Referenced Files in This Document**
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
|
||
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
|
||
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
|
||
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
|
||
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
|
||
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
|
||
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
|
||
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
|
||
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
|
||
- [Browser.Data.Filter.cs](file://ClassicAssist/Browser/Data/Filter.cs)
|
||
- [Browser.Data.FilterType.cs](file://ClassicAssist/Browser/Data/FilterType.cs)
|
||
- [Browser.MacroBrowserControl.xaml.cs](file://ClassicAssist/Browser/MacroBrowserControl.xaml.cs)
|
||
- [Browser.MacroBrowserViewModel.cs](file://ClassicAssist/Browser/MacroBrowserViewModel.cs)
|
||
</cite>
|
||
|
||
## Table of Contents
|
||
1. [Introduction](#introduction)
|
||
2. [Project Structure](#project-structure)
|
||
3. [Core Components](#core-components)
|
||
4. [Architecture Overview](#architecture-overview)
|
||
5. [Detailed Component Analysis](#detailed-component-analysis)
|
||
6. [Dependency Analysis](#dependency-analysis)
|
||
7. [Performance Considerations](#performance-considerations)
|
||
8. [Troubleshooting Guide](#troubleshooting-guide)
|
||
9. [Conclusion](#conclusion)
|
||
10. [Appendices](#appendices)
|
||
|
||
## Introduction
|
||
This document explains the plugin architecture and extension points for ClassicAssist.Avalonia, focusing on:
|
||
- Reflection-based command discovery
|
||
- Dynamic assembly loading and plugin lifecycle management
|
||
- Creating custom commands via HotkeyCommandAttribute
|
||
- Extending the macro system
|
||
- Plugin loading mechanism, dependency resolution, and version compatibility
|
||
- Security considerations, sandboxing, and isolation
|
||
- Distribution format, installation process, and updates
|
||
- Debugging, error handling, and performance monitoring for plugins
|
||
|
||
The goal is to provide both a high-level overview and detailed technical guidance for building robust plugins that integrate with hotkeys, macros, and UI components.
|
||
|
||
## Project Structure
|
||
At a high level, the repository contains:
|
||
- Shared core types and managers (hotkeys, macros, reflection helpers)
|
||
- Avalonia application entry points and engine initialization
|
||
- Launcher utilities for plugin entries and manifests
|
||
- Browser features for browsing and managing macros and metadata
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "Shared Core"
|
||
HKAttr["HotkeyCommandAttribute"]
|
||
HKCmd["HotkeyCommand base"]
|
||
HKMgr["HotkeyManager"]
|
||
MacroInv["MacroInvoker"]
|
||
MacroMgr["MacroManager"]
|
||
Refl["Reflection Helpers"]
|
||
end
|
||
subgraph "Avalonia App"
|
||
Prog["Program"]
|
||
AppXaml["App.axaml.cs"]
|
||
EngineAva["Engine.cs (Avalonia)"]
|
||
end
|
||
subgraph "Launcher"
|
||
PluginEntry["PluginEntry"]
|
||
ManifestEntry["ManifestEntry"]
|
||
ShardMgr["ShardManager"]
|
||
end
|
||
subgraph "Browser"
|
||
DB["Database"]
|
||
Filter["Filter / FilterType"]
|
||
Meta["Metadata"]
|
||
Manifest["Manifest"]
|
||
MBVM["MacroBrowserViewModel"]
|
||
MBCtrl["MacroBrowserControl"]
|
||
end
|
||
Prog --> AppXaml --> EngineAva
|
||
EngineAva --> HKMgr
|
||
EngineAva --> MacroMgr
|
||
HKMgr --> HKAttr
|
||
HKMgr --> HKCmd
|
||
MacroMgr --> MacroInv
|
||
MacroInv --> Refl
|
||
ShardMgr --> PluginEntry
|
||
ShardMgr --> ManifestEntry
|
||
MBVM --> DB
|
||
MBVM --> Filter
|
||
MBVM --> Meta
|
||
MBVM --> Manifest
|
||
MBCtrl --> MBVM
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
|
||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
|
||
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
|
||
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
|
||
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
|
||
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
|
||
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
|
||
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
|
||
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
|
||
- [Browser.Data.Filter.cs](file://ClassicAssist/Browser/Data/Filter.cs)
|
||
- [Browser.Data.FilterType.cs](file://ClassicAssist/Browser/Data/FilterType.cs)
|
||
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
|
||
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
|
||
- [Browser.MacroBrowserViewModel.cs](file://ClassicAssist/Browser/MacroBrowserViewModel.cs)
|
||
- [Browser.MacroBrowserControl.xaml.cs](file://ClassicAssist/Browser/MacroBrowserControl.xaml.cs)
|
||
|
||
**Section sources**
|
||
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
|
||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
|
||
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
|
||
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
|
||
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
|
||
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
|
||
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
|
||
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
|
||
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
|
||
- [Browser.Data.Filter.cs](file://ClassicAssist/Browser/Data/Filter.cs)
|
||
- [Browser.Data.FilterType.cs](file://ClassicAssist/Browser/Data/FilterType.cs)
|
||
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
|
||
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
|
||
- [Browser.MacroBrowserViewModel.cs](file://ClassicAssist/Browser/MacroBrowserViewModel.cs)
|
||
- [Browser.MacroBrowserControl.xaml.cs](file://ClassicAssist/Browser/MacroBrowserControl.xaml.cs)
|
||
|
||
## Core Components
|
||
- Hotkey command discovery and registration
|
||
- Commands are discovered by scanning assemblies for classes implementing a specific base type and decorated with an attribute. The manager registers them into a central registry and binds them to configured shortcuts.
|
||
- Macro execution and extensibility
|
||
- Macros are parsed and executed through an invoker that resolves commands at runtime using reflection. A manager maintains macro definitions and provides APIs for invocation and control.
|
||
- Reflection helpers
|
||
- Utility methods for enumerating types, reading attributes, and constructing instances without hard-coded dependencies.
|
||
- Application engine and bootstrap
|
||
- The Avalonia app initializes subsystems including hotkey and macro managers, ensuring they are ready before user interaction.
|
||
|
||
Key responsibilities:
|
||
- HotkeyCommandAttribute: Declares metadata for discoverable commands (e.g., name, description).
|
||
- HotkeyCommand: Base class or interface for all hotkey commands.
|
||
- HotkeyManager: Scans loaded assemblies, discovers commands, and wires up shortcut handlers.
|
||
- MacroInvoker: Executes macro steps by resolving command implementations dynamically.
|
||
- MacroManager: Manages macro entries, persistence, and orchestration.
|
||
- Reflection: Provides safe and efficient reflection operations used across discovery and invocation.
|
||
|
||
**Section sources**
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
|
||
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
|
||
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
|
||
## Architecture Overview
|
||
The plugin architecture centers around dynamic discovery and late binding:
|
||
- Plugins ship as compiled assemblies placed in designated directories.
|
||
- At startup, the engine scans these assemblies for known patterns (attributes and base types).
|
||
- Discovered commands and macro extensions are registered into centralized managers.
|
||
- Runtime dispatch uses reflection to invoke command implementations based on configuration and user actions.
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant Boot as "Program"
|
||
participant App as "App.axaml.cs"
|
||
participant Eng as "Engine.cs"
|
||
participant HKM as "HotkeyManager"
|
||
participant Mgr as "MacroManager"
|
||
participant Inv as "MacroInvoker"
|
||
participant Ref as "Reflection"
|
||
Boot->>App : Initialize Avalonia
|
||
App->>Eng : Create and configure engine
|
||
Eng->>HKM : Initialize hotkey subsystem
|
||
Eng->>Mgr : Initialize macro subsystem
|
||
HKM->>Ref : Enumerate types in loaded assemblies
|
||
HKM->>HKM : Discover commands via attributes/base types
|
||
Mgr->>Ref : Enumerate macro command types
|
||
Mgr->>Inv : Register resolvers and handlers
|
||
Note over HKM,Inv : Discovery complete; runtime dispatch ready
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
|
||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
|
||
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
|
||
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
|
||
|
||
## Detailed Component Analysis
|
||
|
||
### Hotkey Command System
|
||
Hotkey commands are implemented as classes that derive from a common base and are annotated with a metadata attribute. The hotkey manager performs discovery and registration.
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class HotkeyCommand {
|
||
+Execute()
|
||
+CanExecute() bool
|
||
}
|
||
class HotkeyCommandAttribute {
|
||
+Name
|
||
+Description
|
||
}
|
||
class HotkeyManager {
|
||
+Initialize()
|
||
+Register(command)
|
||
+Unregister(command)
|
||
+OnShortcut(key)
|
||
}
|
||
HotkeyManager --> HotkeyCommand : "discovers and registers"
|
||
HotkeyCommand <.. HotkeyCommandAttribute : "decorated by"
|
||
```
|
||
|
||
- Discovery pattern:
|
||
- Scan assemblies for types implementing the base command type.
|
||
- Require the presence of the metadata attribute to include a command.
|
||
- Registration:
|
||
- Add discovered commands to a registry keyed by identifier.
|
||
- Bind configured shortcuts to command identifiers.
|
||
- Execution:
|
||
- On shortcut activation, resolve the command instance and call Execute.
|
||
|
||
Implementation references:
|
||
- Attribute definition and metadata fields
|
||
- Base command contract
|
||
- Manager initialization, discovery loop, and shortcut wiring
|
||
|
||
**Diagram sources**
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
|
||
**Section sources**
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
|
||
### Macro System Extension Points
|
||
Macros are composed of steps that map to commands. The macro manager stores macro definitions, while the invoker resolves and executes commands at runtime.
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant User as "User"
|
||
participant UI as "UI Layer"
|
||
participant MM as "MacroManager"
|
||
participant MI as "MacroInvoker"
|
||
participant Ref as "Reflection"
|
||
User->>UI : Run macro
|
||
UI->>MM : Invoke(macroId)
|
||
MM->>MI : Resolve steps and parameters
|
||
MI->>Ref : Find command implementation
|
||
MI->>MI : Execute step(s)
|
||
MI-->>MM : Result/status
|
||
MM-->>UI : Completion event
|
||
```
|
||
|
||
Key behaviors:
|
||
- Command resolution:
|
||
- Map macro step names to concrete implementations using reflection.
|
||
- Parameter binding:
|
||
- Parse and bind parameters to method signatures safely.
|
||
- Error propagation:
|
||
- Wrap exceptions during execution and report back to the caller.
|
||
|
||
References:
|
||
- Macro manager for storage and orchestration
|
||
- Invoker for resolution and execution
|
||
- Reflection helpers for safe type inspection
|
||
|
||
**Diagram sources**
|
||
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
|
||
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
|
||
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
|
||
|
||
**Section sources**
|
||
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
|
||
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
|
||
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
|
||
|
||
### Reflection-Based Discovery Flow
|
||
Discovery is driven by scanning loaded assemblies for known patterns.
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start(["Start Discovery"]) --> LoadAssemblies["Load plugin assemblies"]
|
||
LoadAssemblies --> EnumTypes["Enumerate public types"]
|
||
EnumTypes --> CheckBase{"Implements base command?"}
|
||
CheckBase --> |No| NextType["Next type"]
|
||
CheckBase --> |Yes| CheckAttr{"Has metadata attribute?"}
|
||
CheckAttr --> |No| NextType
|
||
CheckAttr --> |Yes| CreateInstance["Create instance"]
|
||
CreateInstance --> Register["Register in manager"]
|
||
Register --> NextType
|
||
NextType --> Done(["Done"])
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
|
||
|
||
**Section sources**
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
|
||
|
||
### Plugin Loading Mechanism and Lifecycle
|
||
Plugins are distributed as assemblies and loaded at runtime. The launcher and browser modules provide structures for manifest and plugin entries, while the engine coordinates initialization.
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant Boot as "Program"
|
||
participant App as "App.axaml.cs"
|
||
participant Eng as "Engine.cs"
|
||
participant SM as "ShardManager"
|
||
participant PE as "PluginEntry"
|
||
participant ME as "ManifestEntry"
|
||
participant DB as "Database"
|
||
Boot->>App : Initialize
|
||
App->>Eng : Configure engine
|
||
Eng->>SM : Load plugin manifests
|
||
SM->>ME : Read manifest entries
|
||
SM->>PE : Build plugin entries
|
||
SM->>DB : Persist/update catalog
|
||
Eng->>Eng : Scan and load plugin assemblies
|
||
Eng->>Eng : Initialize discovered plugins
|
||
```
|
||
|
||
Lifecycle stages:
|
||
- Manifest parsing:
|
||
- Read metadata and dependency information.
|
||
- Assembly loading:
|
||
- Load plugin assemblies into the current context.
|
||
- Initialization:
|
||
- Call plugin entry points if provided.
|
||
- Teardown:
|
||
- Unregister commands and release resources on shutdown.
|
||
|
||
References:
|
||
- Plugin and manifest entry models
|
||
- Database integration for cataloging
|
||
- Engine initialization hooks
|
||
|
||
**Diagram sources**
|
||
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
|
||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
|
||
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
|
||
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
|
||
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
|
||
|
||
**Section sources**
|
||
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
|
||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
|
||
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
|
||
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
|
||
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
|
||
|
||
### Version Compatibility and Dependency Resolution
|
||
Compatibility and dependencies are described via manifest and metadata structures. The loader validates versions and resolves required packages before loading.
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
ReadManifest["Read ManifestEntry"] --> ValidateVersion["Validate target framework/version"]
|
||
ValidateVersion --> ResolveDeps["Resolve dependencies"]
|
||
ResolveDeps --> Missing{"Missing deps?"}
|
||
Missing --> |Yes| ReportError["Report missing dependencies"]
|
||
Missing --> |No| LoadAssembly["Load plugin assembly"]
|
||
LoadAssembly --> InitPlugin["Initialize plugin"]
|
||
InitPlugin --> Ready(["Ready"])
|
||
ReportError --> End(["Abort"])
|
||
```
|
||
|
||
References:
|
||
- Manifest and metadata models
|
||
- Loader logic for validation and resolution
|
||
|
||
**Diagram sources**
|
||
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
|
||
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
|
||
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
|
||
|
||
**Section sources**
|
||
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
|
||
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
|
||
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
|
||
|
||
### UI Integration and Browsing
|
||
The browser component integrates with the macro system and database to present available content and manage metadata.
|
||
|
||
```mermaid
|
||
graph TB
|
||
VM["MacroBrowserViewModel"]
|
||
DB["Database"]
|
||
Filter["Filter / FilterType"]
|
||
Meta["Metadata"]
|
||
Manifest["Manifest"]
|
||
Ctrl["MacroBrowserControl"]
|
||
VM --> DB
|
||
VM --> Filter
|
||
VM --> Meta
|
||
VM --> Manifest
|
||
Ctrl --> VM
|
||
```
|
||
|
||
Responsibilities:
|
||
- Query and filter macro entries
|
||
- Display metadata and manifest details
|
||
- Provide user interactions to install/update content
|
||
|
||
**Diagram sources**
|
||
- [Browser.MacroBrowserViewModel.cs](file://ClassicAssist/Browser/MacroBrowserViewModel.cs)
|
||
- [Browser.MacroBrowserControl.xaml.cs](file://ClassicAssist/Browser/MacroBrowserControl.xaml.cs)
|
||
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
|
||
- [Browser.Data.Filter.cs](file://ClassicAssist/Browser/Data/Filter.cs)
|
||
- [Browser.Data.FilterType.cs](file://ClassicAssist/Browser/Data/FilterType.cs)
|
||
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
|
||
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
|
||
|
||
**Section sources**
|
||
- [Browser.MacroBrowserViewModel.cs](file://ClassicAssist/Browser/MacroBrowserViewModel.cs)
|
||
- [Browser.MacroBrowserControl.xaml.cs](file://ClassicAssist/Browser/MacroBrowserControl.xaml.cs)
|
||
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
|
||
- [Browser.Data.Filter.cs](file://ClassicAssist/Browser/Data/Filter.cs)
|
||
- [Browser.Data.FilterType.cs](file://ClassicAssist/Browser/Data/FilterType.cs)
|
||
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
|
||
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
|
||
|
||
## Dependency Analysis
|
||
The following diagram shows key dependencies between core components involved in plugin discovery and execution.
|
||
|
||
```mermaid
|
||
graph LR
|
||
Program["Program"] --> AppXaml["App.axaml.cs"]
|
||
AppXaml --> EngineAva["Engine.cs"]
|
||
EngineAva --> HKM["HotkeyManager"]
|
||
EngineAva --> MacroMgr["MacroManager"]
|
||
HKM --> HKAttr["HotkeyCommandAttribute"]
|
||
HKM --> HKCmd["HotkeyCommand"]
|
||
MacroMgr --> MacroInv["MacroInvoker"]
|
||
MacroInv --> Refl["Reflection"]
|
||
ShardMgr["ShardManager"] --> PluginEntry["PluginEntry"]
|
||
ShardMgr --> ManifestEntry["ManifestEntry"]
|
||
MBVM["MacroBrowserViewModel"] --> DB["Database"]
|
||
MBVM --> Filter["Filter"]
|
||
MBVM --> Meta["Metadata"]
|
||
MBVM --> Manifest["Manifest"]
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
|
||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
|
||
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
|
||
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
|
||
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
|
||
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
|
||
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
|
||
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
|
||
- [Browser.MacroBrowserViewModel.cs](file://ClassicAssist/Browser/MacroBrowserViewModel.cs)
|
||
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
|
||
- [Browser.Data.Filter.cs](file://ClassicAssist/Browser/Data/Filter.cs)
|
||
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
|
||
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
|
||
|
||
**Section sources**
|
||
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
|
||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
|
||
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
|
||
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
|
||
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
|
||
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
|
||
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
|
||
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
|
||
- [Browser.MacroBrowserViewModel.cs](file://ClassicAssist/Browser/MacroBrowserViewModel.cs)
|
||
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
|
||
- [Browser.Data.Filter.cs](file://ClassicAssist/Browser/Data/Filter.cs)
|
||
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
|
||
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
|
||
|
||
## Performance Considerations
|
||
- Minimize reflection overhead:
|
||
- Cache discovered types and constructed delegates where possible.
|
||
- Avoid heavy work on the UI thread:
|
||
- Use background threads for discovery and I/O; marshal results back to the UI thread.
|
||
- Limit assembly scanning scope:
|
||
- Scan only known directories and avoid unnecessary assemblies.
|
||
- Batch operations:
|
||
- Group registrations and UI updates to reduce churn.
|
||
- Resource cleanup:
|
||
- Ensure plugins release handles and unsubscribe events during teardown.
|
||
|
||
[No sources needed since this section provides general guidance]
|
||
|
||
## Troubleshooting Guide
|
||
Common issues and strategies:
|
||
- Missing dependencies:
|
||
- Validate manifest entries and ensure required packages are present before loading.
|
||
- Type not found:
|
||
- Confirm that command classes implement the expected base type and have the required attribute.
|
||
- Invocation errors:
|
||
- Inspect exception messages from the invoker and verify parameter binding.
|
||
- UI thread violations:
|
||
- Ensure cross-thread calls use the dispatcher or UI invoker.
|
||
- Logging and diagnostics:
|
||
- Centralize logging around discovery and execution paths to capture failures early.
|
||
|
||
Relevant areas to inspect:
|
||
- Hotkey manager discovery and registration
|
||
- Macro invoker resolution and execution
|
||
- Reflection helper usage
|
||
- Engine initialization sequence
|
||
|
||
**Section sources**
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
|
||
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
|
||
## Conclusion
|
||
The ClassicAssist.Avalonia plugin architecture leverages reflection-based discovery and dynamic loading to enable extensible hotkey commands and macro systems. By adhering to the established contracts and leveraging the provided managers, developers can create robust plugins that integrate seamlessly with the host application. Proper attention to security, performance, and error handling ensures reliable operation and maintainability.
|
||
|
||
[No sources needed since this section summarizes without analyzing specific files]
|
||
|
||
## Appendices
|
||
|
||
### How to Create a Custom Hotkey Command
|
||
- Implement a class deriving from the base command type.
|
||
- Decorate the class with the metadata attribute to expose it to discovery.
|
||
- Place the compiled assembly in the plugin directory so the loader can find it.
|
||
- Verify registration by checking the hotkey manager’s registry after startup.
|
||
|
||
References:
|
||
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
|
||
**Section sources**
|
||
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
|
||
### How to Extend the Macro System
|
||
- Define new macro commands by implementing the appropriate interfaces or classes recognized by the invoker.
|
||
- Ensure your command types are discoverable by the macro manager’s scanning routine.
|
||
- Test parameter binding and error handling within your command implementation.
|
||
|
||
References:
|
||
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
|
||
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
|
||
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
|
||
|
||
**Section sources**
|
||
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
|
||
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
|
||
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
|
||
|
||
### Plugin Distribution Format and Installation
|
||
- Package your plugin as a .NET assembly compatible with the host framework.
|
||
- Include a manifest describing metadata, dependencies, and version constraints.
|
||
- Install by placing the assembly and manifest in the expected directories.
|
||
- Use the browser or launcher to validate and update plugins.
|
||
|
||
References:
|
||
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
|
||
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
|
||
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
|
||
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
|
||
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
|
||
|
||
**Section sources**
|
||
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
|
||
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
|
||
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
|
||
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
|
||
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
|
||
|
||
### Security, Sandboxing, and Isolation
|
||
- Prefer least-privilege principles: restrict file and network access where possible.
|
||
- Validate inputs and sanitize outputs to prevent injection.
|
||
- Consider running plugins in isolated contexts if supported by the host environment.
|
||
- Monitor resource usage and enforce timeouts for long-running operations.
|
||
|
||
[No sources needed since this section provides general guidance]
|
||
|
||
### Debugging, Error Handling, and Performance Monitoring
|
||
- Enable detailed logging around discovery and execution paths.
|
||
- Capture and log exceptions with stack traces for diagnostics.
|
||
- Use performance counters or timers to measure hot paths.
|
||
- Validate plugin versions and dependencies prior to loading to fail fast.
|
||
|
||
References:
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
|
||
**Section sources**
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs) |