How can I make these methods generalized?

I have some dictionaries that are all type

Dictionary<Guid, string>

I have a bunch of methods that basically do the same thing, but use different parameters that filter different things. Here are some examples of methods.

private IQueryable<SomeClass> FilterContacts(Filter filter,
        IQueryable<SomeClass> query)
    {
        if (filter.Contacts != null && filter.Contacts.Any())
        {
            result = result.Where(x => filter.Contacts.Contains(x.ContactID));
        }

        return result;
    }

private IQueryable<SomeClass> FilterSomethingElse(Filter filter,
        IQueryable<SomeClass> query)
    {
        if (filter.SomethingElse != null && filter.SomethingElse.Any())
        {
            result = result.Where(x => filter.SomethingElse.Contains(x.SomethingElseID));
        }

        return result;
    }

Thus, all these methods have the same structure, but use different properties in the filter and in the where clause. Is there a way to do this general enough that I can only have one method that can do this?

+4
source share
2 answers

The following solution uses a delegate as a parameter to input some logic needed to make the method more general.

private IQueryable<SomeClass> FilterCommon(IQueryable<SomeClass> query
    , Filter filter
    , Func<Filter, Dictionary<Guid, string>> getDictionary
    , Func<SomeClass, Guid> getKey)
{
    IQueryable<SomeClass> result = null;
    Dictionary<Guid, string> commonDictionary = getDictionary(filter);
    if (commonDictionary != null && commonDictionary.Any())
    {
        result = query.Where(x => commonDictionary.ContainsKey(getKey(x)));
    }

    return result;
}

, Filter , :

private IQueryable<SomeClass> FilterCommon(IQueryable<SomeClass> query
    , Dictionary<Guid, string> commonDictionary
    , Func<SomeClass,Guid> getKey)
{
    IQueryable<SomeClass> result = null;
    if (commonDictionary != null && commonDictionary.Any())
    {
        result = query.Where(x => commonDictionary.ContainsKey(getKey(x)));
    }

    return result;
}

:

//Initializing a few things first...
Filter myFilter = new Filter();
IQueryable<SomeClass> query = new Queryable();//Just a generated type

//This is for my first example from above
FilterCommon(query, myFilter, x => x.Contacts, x => x.ContactID);

//Second example without filter parameter
FilterCommon(query, myFilter.Contacts, x => x.ContactID);
FilterCommon(query, myFilter.SomethingElse, x => x.SomethingElseID);
+4

.

, . , :

public interface IFilterStrategy<T> 
{
    IQueryable<T> Filter(Filter filter, IQueryable<T> query);
}

public class FilterContacts : IFilterStrategy<SomeClass>
{
     public IQueryable<T> Filter(Filter filter, IQueryable<T> query)
     {
        if (filter.Contacts != null && filter.Contacts.Any())
        {
            result = result.Where(x => filter.Contacts.Contains(x.ContactID));
        }

        return result;
     }
}


public class FilterSomethingElse : IFilterStrategy<SomeClass>
{
     public IQueryable<T> Filter(Filter filter, IQueryable<T> query)
     {
        if (filter.SomethingElse != null && filter.SomethingElse.Any())
        {
            result = result.Where(x => filter.SomethingElse.Contains(x.SomethingElseID));
        }
     }

}

, . :

  • IFilterStrategy<SomeClass>
  • IFilterStrategy<SomeClass>, private set()

Filter() , .

0

Source: https://habr.com/ru/post/1655715/


All Articles