Intro
I am building a plugin architecture in my app. The plugins implement a given Interface IBasePlugin, or some other interface which inherited from the base interface:
interface IBasePlugin
interface IMainFormEvents : IBasePlugin
The host is loading the plugin assemblies, and then creates the appropriate object of any class implementing the IBasePlugin interface..
This is the class loading the plugins and instantiating the objects:
public class PluginCore
{
#region implement singletone instance of class
private static PluginCore instance;
public static PluginCore PluginCoreSingleton
{
get
{
if (instance == null)
{
instance = new PluginCore();
}
return instance;
}
}
#endregion
private List<Assembly> _PlugInAssemblies = null;
/// <summary>
/// Gets the plug in assemblies.
/// </summary>
/// <value>The plug in assemblies.</value>
public List<Assembly> PlugInAssemblies
{
get
{
if (_PlugInAssemblies != null) return _PlugInAssemblies;
// Load Plug-In Assemblies
DirectoryInfo dInfo = new DirectoryInfo(
Path.Combine(
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
"Plugins"
)
);
FileInfo[] files = dInfo.GetFiles("*.dll");
_PlugInAssemblies = new List<Assembly>();
if (null != files)
{
foreach (FileInfo file in files)
{
_PlugInAssemblies.Add(Assembly.LoadFile(file.FullName));
}
}
return _PlugInAssemblies;
}
}
List<IBasePlugin> _pluginsList = null;
/// <summary>
/// Gets the plug ins instances.
/// all the plugins are being instanciated ONCE when this if called for the first time
/// every other call will return the existing classes.
/// </summary>
/// <value>The plug ins instances.</value>
public List<IBasePlugin> PlugInInstances
{
get
{
if (_pluginsList != null) return _pluginsList;
List<Type> availableTypes = new List<Type>();
foreach (Assembly currentAssembly in this.PlugInAssemblies)
availableTypes.AddRange(currentAssembly.GetTypes());
// get a list of objects that implement the IBasePlugin
List<Type> pluginsList = availableTypes.FindAll(delegate(Type t)
{
List<Type> interfaceTypes = new List<Type>(t.GetInterfaces());
return interfaceTypes.Contains(typeof(IBasePlugin));
});
// convert the list of Objects to an instantiated list of IBasePlugin
_pluginsList = pluginsList.ConvertAll<IBasePlugin>(delegate(Type t) { return Activator.CreateInstance(t) as IBasePlugin; });
return _pluginsList;
}
}
The Question
Currently, any module which supports the plugins, uses the PlugInInstances property to retrieve the IBasePlugins list. Then it iterates the objects querying who is implementing a given child interface.
foreach (IBasePlugin plugin in PluginCore.PluginCoreSingleton.PlugInInstances)
{
if (plugin is IMainFormEvents)
{
// Do something
}
}
I would like to improve this technique by having a function that receives a given child interface, and return a list of those interface. The catch is that no casting should be done in the caller.
pseudo code:
void GetListByInterface(Type InterfaceType, out List<InterfaceType> Plugins)
Do you have a recommendation on how to implement this?