An open API service indexing awesome lists of open source software.

https://github.com/prashantvc/plugindemo

Plugin Demonstration
https://github.com/prashantvc/plugindemo

Last synced: 8 months ago
JSON representation

Plugin Demonstration

Awesome Lists containing this project

README

          

# MEF Plugin Demo

This solution demonstrates the use of the Managed Extensibility Framework (MEF) to create a plugin-based application in .NET that can load plugins at runtime.

## Project Structure

The solution consists of the following projects:

1. **PluginDemoApp**: A console application that hosts and discovers plugins.
2. **PluginDemo.Shared**: A class library containing shared interfaces and base classes for plugins.
3. **PluginDemo.CharacterCountPlugin**: A plugin that counts characters in text.
4. **PluginDemo.ReverseStringPlugin**: A plugin that reverses text.
5. **PluginDemo.UpperCasePlugin**: A plugin that converts text to uppercase.

## How It Works

The MEF framework allows for creating extensible applications through the use of:

- **Exports**: Components that provide functionality (plugins)
- **Imports**: Components that consume functionality (the host application)
- **Composition**: The process of connecting exports to imports

In this demo:

- `IPlugin` interface in the Shared project defines the contract that all plugins must implement.
- `PluginBase` abstract class provides a base implementation for plugins.
- The Plugins project contains sample plugins that are exported using the `[Export]` attribute.
- The main application imports plugins using the `[ImportMany]` attribute and composes them using a `CompositionContainer`.

## Running the Demo

1. Build the solution
2. Copy the plugin DLLs to the Plugins directory (you can use the provided script)

```powershell
./CopyPlugins.ps1
```

3. Run the PluginDemoApp console application

```powershell
dotnet run --project ./PluginDemoApp/PluginDemoApp.csproj
```

4. The application will discover and display available plugins
5. Select a plugin by number and provide input to see the plugin in action

## Loading Plugins at Runtime

This demo showcases how to load plugins at runtime without recompiling the main application:

1. The application checks for plugins in the "Plugins" directory
2. It uses `Assembly.LoadFrom()` to dynamically load assemblies with name convention `PluginDemo.*.dll`
3. MEF discovers classes with `[Export(typeof(IPlugin))]` attribute
4. The plugins are composed and available for use immediately

The included `CopyPlugins.ps1` script helps copy the plugin DLLs to the correct location:

```powershell
# Define plugin projects and the target directory
$pluginProjects = @(
"PluginDemo.CharacterCountPlugin",
"PluginDemo.ReverseStringPlugin",
"PluginDemo.UpperCasePlugin"
)
$pluginsDir = ".\PluginDemoApp\bin\Debug\net9.0\Plugins"

# Create the Plugins directory if it doesn't exist
if (-not (Test-Path $pluginsDir)) {
New-Item -Path $pluginsDir -ItemType Directory | Out-Null
Write-Host "Created Plugins directory: $pluginsDir"
}

# Copy plugin DLLs to the Plugins directory
foreach ($project in $pluginProjects) {
$sourceDll = ".\$project\bin\Debug\net9.0\$project.dll"
if (Test-Path $sourceDll) {
Copy-Item -Path $sourceDll -Destination $pluginsDir -Force
Write-Host "Copied $sourceDll to $pluginsDir"
} else {
Write-Host "Warning: $sourceDll not found. Build the project first."
}
}
```

## Extending with New Plugins

To create a new plugin:

1. Create a new class library project (e.g., "PluginDemo.MyNewPlugin")
2. Add a reference to the PluginDemo.Shared project
3. Implement the `IPlugin` interface or inherit from `PluginBase`
4. Add the `[Export(typeof(IPlugin))]` attribute to your plugin class
5. Build and copy the DLL to the Plugins directory (or update CopyPlugins.ps1)

## Plugin Examples Included

1. **Upper Case Converter**: Converts input text to uppercase
2. **String Reverser**: Reverses the characters in the input text
3. **Character Counter**: Analyzes and counts different types of characters in the input

## Benefits of MEF

- Loose coupling between components
- Dynamic discovery of extensions at runtime
- No need to modify host application to add new plugins
- Metadata-driven capabilities through attributes