检索实现给定接口的对象列表 [英] Retrieve a list of object implementing a given interface
问题描述
简介
我正在我的应用程序中构建插件架构.插件实现给定的接口IBasePlugin,或从基本接口继承的其他接口:
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
宿主正在加载插件程序集,然后创建实现 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;
}
}
问题
目前,任何支持插件的模块都使用 PlugInInstances 属性来检索 IBasePlugins 列表.然后它迭代查询谁在实现给定子接口的对象.
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.
伪代码:
void GetListByInterface(Type InterfaceType, out List<InterfaceType> Plugins)
您有关于如何实施的建议吗?
Do you have a recommendation on how to implement this?
推荐答案
你可以试试这样的:
void GetListByInterface<TInterface>(out IList<TInterface> plugins) where TInterface : IBasePlugin
{
plugins = (from p in _allPlugins where p is TInterface select (TInterface)p).ToList();
}
这篇关于检索实现给定接口的对象列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!