- fadd-15373.zip
- trunk
- dlls
- xunit.dll
- Examples
- Plugins
- ExampleApplication.Shared
- ExampleApplication
- ExamplePlugin.Shared
- ExamplePlugin
- Fadd.Globalization.Yaml
- fadd.sln
- fadd
|
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace Fadd.Plugins
{
/// <summary>
/// General purpose plugin finder class.
/// </summary>
/// <remarks>
/// This class scans a directory after all classes that contains the specified types.
/// All assembly checking is done in a separate app domain, which means that no dlls are loaded
/// during the process.
/// </remarks>
[Serializable]
public class PluginFinder
{
private List<PluginTypeInfo> _plugins;
/// <summary>
/// Initializes a new instance of the <see cref="PluginFinder"/> class.
/// </summary>
public PluginFinder()
{
_plugins = new List<PluginTypeInfo>();
}
private void Assign(List<PluginTypeInfo> plugins)
{
_plugins = plugins;
}
/// <summary>
/// All found plugins
/// </summary>
public List<PluginTypeInfo> Plugins
{
get { return _plugins; }
}
/// <summary>
/// Finds the specified full path.
/// </summary>
/// <param name="fullPath">Path and wildcards.</param>
/// <param name="types">Types wanted.</param>
/// <example>
/// <code>
/// List>Type< types = new List>Type<();
/// types.Add(typeof(IPlayer));
/// types.Add(typeof(IViewer));
/// finder.Find("C:\\myapp\\plugins\\plugin*.dll", types);
/// </code>
/// </example>
/// <exception cref="ReflectionTypeLoadException"></exception>
/// <exception cref="TypeLoadException"></exception>
public void Find(string fullPath, IEnumerable<Type> types)
{
AppDomain domain = AppDomain.CreateDomain("ModuleLoader");
PluginFinder finder = (PluginFinder)domain.CreateInstanceFromAndUnwrap(
GetType().Assembly.Location ?? string.Empty, GetType().Namespace + ".PluginFinder");
finder.FindInternal(Environment.CurrentDirectory, types);
Assign(finder.Plugins);
AppDomain.Unload(domain);
}
/// <summary>
/// Finds the specified full path.
/// </summary>
/// <param name="fullPath">Path and wildcards.</param>
/// <param name="types">Types wanted.</param>
/// <example>
/// <code>
/// List>Type< types = new List>Type<();
/// types.Add(typeof(IPlayer));
/// types.Add(typeof(IViewer));
/// finder.Find("C:\\myapp\\plugins\\plugin*.dll", types);
/// </code>
/// </example>
/// <exception cref="TypeLoadException"></exception>
protected void FindInternal(string fullPath, IEnumerable<Type> types)
{
foreach (string fileName in Directory.GetFiles(fullPath, "*.dll"))
{
try
{
Assembly asm;
byte[] publicKey = null;
try
{
asm = Assembly.LoadFrom(fileName);
AssemblyName assemblyName = asm.GetName();
if (assemblyName != null)
publicKey = assemblyName.GetPublicKey();
}
catch (FileLoadException err)
{
Console.WriteLine(err);
continue;
}
PluginTypeInfo plugin = null;
foreach (Type wantedType in types)
{
if (wantedType.IsInterface)
{
foreach (Type type in asm.GetTypes())
{
if (type.GetInterface(wantedType.Name) != null)
Add(ref plugin, asm, type, publicKey);
}
}
else if (wantedType.IsClass)
{
foreach (Type type in asm.GetTypes())
{
if (type.IsSubclassOf(wantedType))
Add(ref plugin, asm, type, publicKey);
}
}
}
}
catch (ReflectionTypeLoadException e)
{
throw new TypeLoadException("Couldn't load plugin: " + fileName, e);
}
}
}
/// <summary>
/// Adds the specified plugin.
/// </summary>
/// <param name="plugin">The plugin.</param>
/// <param name="assembly">Assembly that the plugin resides in.</param>
/// <param name="type">Plugin interface type.</param>
/// <param name="publicKey">Public key, should be used to decide the amount of access for the module.</param>
protected void Add(ref PluginTypeInfo plugin, Assembly assembly, Type type, byte[] publicKey)
{
if (plugin == null)
{
plugin = new PluginTypeInfo(assembly.FullName, type, publicKey);
_plugins.Add(plugin);
}
else
plugin.Add(type);
}
#region Nested type: Plugin
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.