繁体   English   中英

模式根据字符串列表返回对象?

[英]Pattern to return objects based on a list of strings?

这让我很伤心,因为我觉得我以前见过的东西,但是我的搜索结果是空的,我还没有承诺记忆的各种模式(还)。

情况

我有一个搜索网格,允许用户根据多个属性进行过滤。 用户想要的过滤器通过NameValueCollection传递并解析出来。

目前,我们的遗留应用程序会在单独的if语句中检查每个可能的过滤器,然后运行自定义代码。 因为圈复杂度不是我的事,30个几乎相同的if语句会让我烦恼。

走向更好的方式

我没有继续以硬编码方式检查每个项目,而是重新编写了解析器,现在我可以快速获取将要应用的所有过滤器的列表。 我也将过滤器本身重构为自己的类。

所以,我有一个字符串形式的过滤器列表(“名称”,“BirthDate”等)和一堆类( NameFilterBirthDateFilter等)

问题

获取表示过滤器名称的字符串列表并将其转换为这些过滤器对象本身的列表的标准方法是什么?

我想我可以使用FilterLocator LocateFilter(string filterName)方法做一些FilterLocator ,但这似乎会导致一个很长的switch语句,看起来有点粗糙。

我明白这是朝着某种IoC / DI解决方案的方向发展,但我还不知道要么完全实现它。

谢谢你的想法!

使用字典,其中键是您的过滤器名称,值是您的过滤器对象。

不是硬编码这个字典,而是创建一个自定义属性,为每个过滤器对象提供一个过滤器名称。 然后,使用反射来查找这些对象并创建可以在以后使用的静态字典。 这样,根本没有对各个过滤器映射进行硬编码。

以下是为此设置的示例:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class FilterNameAttribute : Attribute
{
    public FilterNameAttribute(string filterName)
    {
        FilterName = filterName;
    }

    public string FilterName { get; private set; }
}

[FilterName("MyFilterName")]
public class MyFilter
{
    //Do whatever you want here
}

public static class FilterHelper
{
    static Dictionary<string, Type> _filterTypesDict;

    static FilterHelper()
    {
        var assembly = Assembly.GetExecutingAssembly();

        _filterTypesDict = assembly.GetTypes()
            .Select(type => new { type, attrib = (FilterNameAttribute)type.GetCustomAttributes(typeof(FilterNameAttribute), false).FirstOrDefault() })
            .Where(x => x.attrib != null)
            .ToDictionary(x => x.attrib.FilterName, x => x.type);
    }

    public static Type GetFilterType(string filterName)
    {
        Type filterType;

        if (!_filterTypesDict.TryGetValue(filterName, out filterType))
        {
            throw new Exception("Unknown Filter Name.");
        }

        return filterType;
    }

    public static object GetFilter(string filterName)
    {
        return Activator.CreateInstance(GetFilterType(filterName));
    }
}

就像在评论中我肯定会为您的过滤器创建一个字典。 另外,我将使用Name属性和Apply方法为每个过滤器创建一个基类。 当您的应用程序启动时,您可以通过基本过滤器类收集带有反射的过滤器类,并使用Name属性作为键填充过滤器字典(或者您可以只使用过滤器类的名称),这样您就不会甚至需要手动建立字典,每次添加过滤器类时它都会自动出现在字典中。 这将允许您的LocateFilter(string filterName)方法非常简单明了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM