簡體   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