Lately I seem to be working with lots of request/response stuff and I thought of creating something generic.
I have the following but I am not happy about creating multiple ifs statements and I would like to avoid them.
The idea is this:
Regardless of the request /response process them.
How can I remove these if statement within my generic request Handler?
Code
class Program
{
private static void Main()
{
IRequestResponseFactory factory = new RequestResponseFactory();
var customerRequest = new CustomerRequest { Name = "Joe", Surname = "Bloggs" };
var customerResponse = factory.ProcessRequest<CustomerRequest, CustomerResponse>(customerRequest);
var billRequest = new BillRequest() { Amount = 100m };
var billResponse = factory.ProcessRequest<BillRequest, BillResponse>(billRequest);
Console.WriteLine(billResponse.Success);
Console.WriteLine(customerResponse.Success);
Console.ReadKey();
}
}
public class CustomerRequest : IRequestData<CustomerResponse>
{
public string Name { get; set; }
public string Surname { get; set; }
}
public class CustomerResponse
{
public bool Success { get; set; }
}
public class BillRequest : IRequestData<BillResponse>
{
public decimal Amount { get; set; }
}
public class BillResponse
{
public bool Success { get; set; }
}
public interface IRequestData<TResponse>
{
}
public interface IRequestHandler<TRequest, TResponse> where TRequest : IRequestData<TResponse>
{
TResponse ProcessRequest(TRequest request);
}
public interface IRequestResponseFactory
{
TResponse ProcessRequest<TRequest, TResponse>(TRequest request) where TRequest : IRequestData<TResponse>;
}
class RequestResponseFactory : IRequestResponseFactory
{
public TResponse ProcessRequest<TRequest, TResponse>(TRequest request) where TRequest : IRequestData<TResponse>
{
var handler = new GenericRequestHandler<TRequest, TResponse>();
TResponse response = handler.ProcessRequest(request);
return response;
}
}
public class GenericRequestHandler<TRequest, TResponse> : IRequestHandler<TRequest, TResponse> where TRequest : IRequestData<TResponse>
{
public TResponse ProcessRequest(TRequest request)
{
var response = default(TResponse);
//How do I avoid this if statements????
if (request is IRequestData<CustomerResponse>)
{
var tempResponse = new CustomerResponse { Success = true };
response = (TResponse)Convert.ChangeType(tempResponse, typeof(TResponse));
return response;
}
if (request is IRequestData<BillResponse>)
{
var tempResponse = new BillResponse { Success = false };
response = (TResponse)Convert.ChangeType(tempResponse, typeof(TResponse));
return response;
}
return response;
}
}
You can replace the
GenericRequestHandler<TRequest, TResponse>class with specializedIRequestHandlers and have the factory keep track of all available such handlers via reflection.Concretely, these could be the handlers:
Now, the factory, instead of just forwarding the call to the generic handler that contains the
ifugliness, will do the following:IRequestHandler<TRequest, TResponse>TRequesttype and the value is the handler typeThis is a possible implementation for the factory class:
The complete program with working sample is available at http://ideone.com/TxRnEi.
The output is the same as the output of the original program, but now the program allows you to add new types of requests and new types of handlers and will be able to dynamically use them at run time, without you having to write the long
if/casestatements to specify when they should be used.