Here’s a little class I whipped up some weeks back when I was bored, this does what you’re asking of – if I understand the question correctly.
Your applications must implement IPlugin, and must be dropped in a “Plugins” folder in the executing directory.
public interface IPlugin
{
void Initialize();
}
public class PluginLoader
{
public List<IPlugin> LoadPlugins()
{
List<IPlugin> plugins = new List<IPlugin>();
IEnumerable<string> files = Directory.EnumerateFiles(Path.Combine(Directory.GetCurrentDirectory(), "Plugins"),
"*.dll",
SearchOption.TopDirectoryOnly);
foreach (var dllFile in files)
{
Assembly loaded = Assembly.LoadFile(dllFile);
IEnumerable<Type> reflectedType =
loaded.GetExportedTypes().Where(p => p.IsClass && p.GetInterface(nameof(IPlugin)) != null);
plugins.AddRange(reflectedType.Select(p => (IPlugin) Activator.CreateInstance(p)));
}
return plugins;
}
}
Following from Paul’s recommendation in the comments, here’s a variation using MEF, referencing the System.ComponentModel.Composition
namespace.
namespace ConsoleApplication18
{
using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.IO;
using System.Linq;
public interface IPlugin
{
void Initialize();
}
class Program
{
private static CompositionContainer _container;
static void Main(string[] args)
{
AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog(Path.Combine(Directory.GetCurrentDirectory(), "Plugins")));
_container = new CompositionContainer(catalog);
IPlugin plugin = null;
try
{
_container.ComposeParts();
// GetExports<T> returns an IEnumerable<Lazy<T>>, and so Value must be called when you want an instance of the object type.
plugin = _container.GetExports<IPlugin>().ToArray()[0].Value;
}
catch (CompositionException compositionException)
{
Console.WriteLine(compositionException.ToString());
}
plugin.Initialize();
Console.ReadKey();
}
}
}
and the DLL file – also referencing the System.ComponentModel.Composition
namespace to set the ExportAttribute
namespace FirstPlugin
{
using System.ComponentModel.Composition;
[Export(typeof(IPlugin))]
public class NamePlugin : IPlugin
{
public void Initialize() { }
}
}
13
solved List of classes in an assembly C#