【问题标题】:Get applicable interface implementation获取适用的接口实现
【发布时间】:2016-12-20 23:49:59
【问题描述】:

我正在努力为我正在做的事情找到一个好的设计。例如,考虑一个接受字符串参数并返回处理后的字符串的 TextProcessor 类。

现在在我的实现中有许多不同的TextProcessors,每个都能够处理自己定义的字符串集。每个处理器中有两种值得注意的方法:

bool CanProcess(string text);

string Process(string text);

实际上,这些可以标记为静态,但为了实现通用接口,我没有将它们设置为静态。

除了这些TextProcessor 之外,还有一个静态的TextProcessorFinder 类。顾名思义,它会找到最好的 TextProcessor 并处理输入。

public static class TextProcessorFinder
{
    private static List<ITextProcessor> _processors;

    static TextProcessorFinder()
    {
        _processors = Assembly.GetExecutingAssembly().GetTypes()
            .Where(t => t.GetInterfaces().Contains(typeof(ITextProcessor))
            && t.IsClass && !t.IsAbstract)
            .Select(t => (ITextProcessor)Activator.CreateInstance(t))
            .Where(t => t.IsActive)
            .ToList();
    }

    public static ITextProcessor GetTextProcessor(string text)
    {
        return _processors.Where(p => p.CanProcess(text))
            .OrderByDescending(p => p.Priority)
            .FirstOrDefault();
    }
}

我讨厌这种方法的地方在于,我必须为每个已知的 TextProcessor 创建一个实例,才能调用它们的 CanProcess 函数。

我尝试用一​​个简单的 Func 创建一个属性来模拟 CanProcess 函数:

[AttributeUsage(AttributeTargets.Class)]
public class TextProcessorAttribute : Attribute
{
    private Func<string, bool> func;

    public TextProcessorAttribute(Func<string, bool> func)
    {
        this.func = func;
    }
}

public interface ITextProcessor
{
    bool IsActive { get; }

    int Priority { get; }

    bool CanProcess(string text);

    string Process(string text);
}

// Hard-coded to true
[TextProcessor((s) => { return true; })]
public class SampleTextProcessor : ITextProcessor
{
    // Implement ITextProcessor
}

但遗憾的是,Func 不是有效的属性参数类型。

最好的方法是什么?

【问题讨论】:

    标签: c# interface activator


    【解决方案1】:

    在我看来,创建这些实例是最好的方法。真的没有理由不这样做。实例很便宜,如果您不在构造函数中做任何工作,创建它们也很便宜 - 无论如何您都不应该这样做。

    【讨论】:

    • 我想这行得通。它们确实很便宜,但是为可能是静态的方法(接口实现除外)创建一堆实例让我畏缩。
    • @ZuiqPazu:不需要让你畏缩,完全没问题。
    【解决方案2】:

    使用CanProcess 方法,您可以询问每个派生的 ITextProcessor 是否可以处理文本。我认为这没问题。 也许在 ITextProcessor 的实现中存在某种特殊化,在这种情况下,您可以创建更具体的接口,ITextTypeAProcessor、ITextTypeBProcessor 等。然后您可以在 GetTextProcessor 方法中按接口进行过滤。

    【讨论】:

    • 我知道你在做什么。然而,目前我没有任何进一步的细节可供过滤。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 1970-01-01
    • 2021-09-02
    • 2023-03-18
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多