Ahmad
Ahmad

Reputation: 13426

A generic predicate which can be customized by caller?

I have a bunch of Predicates defined like this, each checking for a different http status code:

readonly Predicate<HttpResponseData> createdHttpStatusPredicate = (HttpResponseData responseData) => {
    return responseData.StatusCode == HttpStatusCode.Created;
};

readonly Predicate<HttpResponseData> okHttpStatusPredicate = (HttpResponseData responseData) => {
    return responseData.StatusCode == HttpStatusCode.OK;
};

...

I'm passing them into the following method like this (code has been simplified a little to cut out irrelevant details):

public static async Task<HttpResponseData> HttpCaller(HttpMethod requestMethod, Predicate<HttpResponseData> predicate)
{
    HttpResponseData response = await SendHttpRequest(requestMethod);

    if (predicate(response) == true)
        return response;
    else
        return null;
}

Here is a sample call sending one predicate into above method:

HttpResponseData data = await HttpRequestUtils.HttpCaller(HttpMethod.Post, createdHttpStatusPredicate);

I'm wondering, can I combine all the predicates in some generic predicate, or perhaps somehow specify the http status to look for into the predicate when I'm calling HttpCaller ?

Yes, I know the above example doesn't make much sense as I can just pass the http status I'm looking for into HttpCaller directly without going through a predicate, but in my case HttpCaller can receive my complex predicates as inputs too, based on where HttpCaller is being called from

Upvotes: 0

Views: 711

Answers (1)

Iliar Turdushev
Iliar Turdushev

Reputation: 5213

The next two approaches can be used to get rid of all the predicates that only check for HttpStatusCode.


1. Create a method that creates a Predicate for a given HttpStatusCode:

public static Predicate<HttpResponseData> CreatePredicateByHttpStatusCode(HttpStatusCode status)
{
    return r => r.StatusCode == status;
}

And then use this method when you need a Predicate that only checks for a given HttpStatusCode:

var result = await HttpCaller(httpMethod, CreatePredicateByHttpStatusCode(HttpStatusCode.OK));

2. Create an overload of the method HttpCaller that accepts HttpStatusCode and only checks for a given HttpStatusCode:

// This is your current method. It accepts a common Predicate that is used
// to check for complex conditions.
public static async Task<HttpResponseData> HttpCaller(HttpMethod requestMethod, Predicate<HttpResponseData> predicate)
{
    HttpResponseData response = await SendHttpRequest(requestMethod);

    if (predicate(response) == true)
        return response;
    else
        return null;
}

// This is a new Method. It accepts HttpStatusCode instead of the Predicate.
// It can be used for checking only for HttpStatusCode.
public static async Task<HttpResponseData> HttpCaller(HttpMethod requestMethod, HttpStatusCode status)
{
    // Here your original method HttpCaller is used.
    return await HttpCaller(requestMethod, r => r.StatusCode == status);
}

Overloaded form of the HttpCaller can be used when you need to check only for HttpStatusCode:

var result = await HttpCaller(httpMethod, HttpStatusCode.OK);

Upvotes: 1

Related Questions