我有一个界面列表:
private IList<IPlugin> plugins;
我希望有一个访问器方法,允许用户获取所述接口的实现者列表:
public IList<T> GetPlugins<T>() where T : IPlugin
{
// Create list
}
我已经看过迭代装配的多个例子。我已经实现了这一点,因为我正在使用MEF,所以我的plugins
已经填充了继承IPlugin的导出类。
我遇到的问题是使用程序集的方法不会转换为我的列表设置。我不熟悉linq,知道其他问题与我想要实现的内容之间有什么不同。
这些是我看过的问题:
为了清晰起见进行编辑:
假设我有一些课程:
public class Setting : IPlugin {}
public class AppearanceSetting : Setting {}
public class WebSettings : Setting {}
如果我有一个IPlugin列表,我想从上面使用我的访问者调用。
var settings = GetPlugins<Setting>(); // Get all implementors of Setting
我如何从List
那样做?我发现的例子都使用了Assembly。但是,如果我已经使用MEF完成了这项工作,那么操纵IList获取我需要的类的最佳方法是什么?如果可能的话。
答案 0 :(得分:2)
您可以通过以下方式获取插件类:
using System.Collections.Generic;
using System;
using System.Linq;
IEnumerable<Type> getAllTheTypes() {
return AppDomain.CurrentDomain.GetAssemblies().SelectMany(ass => ass.GetTypes());
}
IEnumerable<Type> getPluginTypes<T>() where T : IPlugin {
return getAllTheTypes()
.Where(typeof(T).IsAssignableFrom);
}
IEnumerable<Type> getPluginClassesWithDefaultConstructor<T>() where T : IPlugin {
return getPluginTypes<T>()
.Where(cls => !cls.IsAbstract)
.Where(cls => cls.GetConstructor(new Type[] { }) != null);
}
您可以实例化它们并制作列表:
List<T> makePlugins<T>() where T : IPlugin {
return getPluginClassesWithDefaultConstructor<T>()
.Select(cls => (T)cls.GetConstructor(new Type[] { }).Invoke(new object[] { }))
.ToList();
}
但是,如果您只需将List<IPlugin>
转换为List<Setting>
,plugins.OfType<Setting>().ToList()
可能就是您想要的