我一直在尝试设计一个有效的界面,我正用于一些插件。我以为我找到了一个不错的界面,但试图实现它并不顺利。所以我希望看看这里是否有人对如何做到这一点有更好的建议。它的错误是“不包含'GetEnumerator'的公共定义”
插件界面:
namespace ALeRT.PluginFramework
{
public interface IQueryPlugin
{
string PluginCategory { get; }
string Name { get; }
string Version { get; }
string Author { get; }
System.Collections.Generic.List TypesAccepted { get; }
}
interface IQueryPluginRBool : IQueryPlugin
{
bool Result(string input, bool sensitive);
}
interface IQueryPluginRString : IQueryPlugin
{
string Result(string input, bool sensitive);
}
}
本质上,我试图获取应该使用的类型列表(类型可以是URL,名称,电子邮件,IP等),并将它们与查询插件中的值进行比较。每个查询插件可能都有它接受的多种类型。当它们匹配时,它会执行查询插件中的操作。
[ImportMany]
public IEnumerable<IQueryPlugin> QPlugins { get; set; }
private void QueryPlugins(List<string> val, bool sensitive)
{
foreach (string tType in val) //Cycle through a List<string>
{
foreach (var qPlugins in this.QPlugins) //Cycle through all query plugins
{
foreach (string qType in qPlugins) //Cycle though a List<string> within the IQueryPlugin interface AcceptedTypes
{
if (qType == tType) //Match the two List<strings>, one is the AcceptedTypes and the other is the one returned from ITypeQuery
{
//Do stuff here
}
}
}
}
}
答案 0 :(得分:1)
您的代码
foreach (string qType in qPlugins)
{
if (qType = tType)
{
//Do stuff here
}
}
不行。您必须遍历qPlugins.TypeAccepted
答案 1 :(得分:1)
首先。不要暴露列表(如下面的行),因为它违反了Demeter法则。这意味着该插件不会如何控制它自己的列表。任何有插件引用的人都可以修改列表。
System.Collections.Generic.List TypesAccepted { get; }
这样更好:
IEnumerable<TheType> TypesAccepted { get; }
但是仍然允许任何人修改列表的元素(不知道插件)。如果元素是不可变的,那就好了。
更好的解决方案是在插件界面中创建方法。例如,有一个访问者模式方法:
public interface IPluginTypeVisitor
{
void Visit(AcceptedType type);
}
public interface IQueryPlugin
{
string PluginCategory { get; }
string Name { get; }
string Version { get; }
string Author { get; }
void VisitTypes(IPluginTypeVisitor visitor);
}
但是你的循环示例中最好的解决方案就是:
public interface IQueryPlugin
{
string PluginCategory { get; }
string Name { get; }
string Version { get; }
string Author { get; }
bool IsTypeAcceptable(TheTypeType type); // get it, thetypetype? hahaha
}
private void QueryPlugins(List<string> val, bool sensitive)
{
foreach (string tType in val) //Cycle through a List<string>
{
foreach (var plugin in this.QPlugins) //Cycle through all query plugins
{
if (plugin.IsTypeAcceptable(tType))
//process it here
}
}
}