Module Registry
Dynamic module/plugin registry with compile-time discovery and runtime instantiation for Rust.
Features
- Compile-Time Discovery: Automatic module registration using
inventory - Runtime Instantiation: Create modules dynamically by name
- Type-Safe: Generic factory functions with trait objects
- Thread-Safe: Built on
RwLockfor concurrent access - Zero-Cost: Minimal runtime overhead
- Flexible: Works with any module type and custom configuration
Installation
[]
= "0.1"
# With tracing support
= { = "0.1", = ["tracing"] }
Quick Start
1. Define Your Module Trait
use Module;
use Result;
2. Implement a Module
;
3. Register and Use
use ModuleRegistry;
// Create registry
let registry = new;
// Register module
registry.register;
// Create instance
let any_module = registry.create_any?;
let module = any_module.?;
// Use it
let result = module.process?;
assert_eq!;
Advanced Usage
Global Registry
Use a single global registry across your application:
use ModuleRegistry;
// Access global registry
let global = global;
// Register modules
global.register;
global.register;
// Use anywhere in your app
let module = global.create_any?;
Compile-Time Registration
Use the register_module! macro for automatic registration:
use register_module;
register_module!;
// Module is automatically registered at startup
Module Metadata
Store and retrieve metadata about modules:
registry.register_with_metadata;
// Later, retrieve metadata
if let Some = registry.get_metadata
List Available Modules
let modules = registry.list_modules;
for module_name in modules
// Check if specific module exists
if registry.has_module
Use Cases
Plugin Systems
Build extensible applications with runtime-loaded plugins:
// Define plugin interface
// Users can add plugins at compile time or runtime
registry.register;
// Load and execute plugins dynamically
for plugin_name in registry.list_modules
Service Locator
Implement the service locator pattern:
// Register services
registry.register;
registry.register;
// Locate and use services
let db = registry.create_any?;
Provider Pattern
Register multiple providers for the same interface:
// Register different providers
registry.register;
registry.register;
registry.register;
// Choose provider at runtime
let provider_name = config.get_provider;
let provider = registry.create_any?;
API Reference
ModuleRegistry::new()
Create a new empty registry.
ModuleRegistry::global()
Get the global singleton registry instance.
register(name, module_type, factory)
Register a module with a factory function.
create_any(name) -> Result<Box<dyn Any + Send + Sync>>
Create a module instance (returns Any, must downcast).
create<T>(name) -> Result<Box<T>>
Create and downcast to a specific type (experimental).
list_modules() -> Vec<String>
Get all registered module names.
has_module(name) -> bool
Check if a module is registered.
get_metadata(name) -> Option<ModuleMetadata>
Get metadata for a module.
clear()
Clear all registered modules (useful for testing).
Testing
# Run tests
# Run with tracing
# Run example
Architecture
┌─────────────────────────┐
│ Application Code │
└─────────────────────────┘
│
│ register/create
▼
┌─────────────────────────┐
│ ModuleRegistry │
│ (Thread-Safe Store) │
└─────────────────────────┘
│
├──── Module 1 (Factory Fn)
├──── Module 2 (Factory Fn)
└──── Module N (Factory Fn)
│
│ create instance
▼
┌────────────────┐
│ Box<dyn Trait> │
└────────────────┘
Performance
- Registration: O(1) - HashMap insertion
- Lookup: O(1) - HashMap access
- Memory: Minimal - only stores metadata and function pointers
- Thread Safety: RwLock allows multiple concurrent readers
Comparison
| Feature | module-registry | Other Solutions |
|---|---|---|
| Compile-time discovery | ✅ inventory | Manual |
| Type-safe | ✅ Generic traits | Varies |
| Thread-safe | ✅ RwLock | Varies |
| Metadata | ✅ Full | Limited |
| Global registry | ✅ Built-in | DIY |
| Testing support | ✅ clear() method | Limited |
Origin
Extracted from Red Asgard, a security platform where it manages dynamic loading of analyzers, language processors, and security tools.
License
Licensed under MIT License. See LICENSE-MIT for details.
Contributing
Contributions welcome! Areas of interest:
- Additional examples
- Performance optimizations
- Documentation improvements
- Type-safety enhancements
Contact
- Author: Red Asgard
- Email: hello@redasgard.com
- GitHub: https://github.com/redasgard