using System; using System.Collections.Generic; using System.Linq; internal class Program { public static void Main() { IRequestResponseFactory factory = new RequestResponseFactory(); var customerRequest = new CustomerRequest { Name = "Joe", Surname = "Bloggs" }; var customerResponse = factory.ProcessRequest(customerRequest); var billRequest = new BillRequest { Amount = 100m }; var billResponse = factory.ProcessRequest(billRequest); Console.WriteLine(billResponse.Success); Console.WriteLine(customerResponse.Success); Console.ReadKey(); } } public class CustomerRequest : IRequestData { public string Name { get; set; } public string Surname { get; set; } } public class CustomerResponse { public bool Success { get; set; } } public class BillRequest : IRequestData { public decimal Amount { get; set; } } public class BillResponse { public bool Success { get; set; } } public interface IRequestData { } public interface IRequestHandler where TRequest : IRequestData { TResponse ProcessRequest(TRequest request); } public interface IRequestResponseFactory { TResponse ProcessRequest(TRequest request) where TRequest : IRequestData; } class RequestResponseFactory : IRequestResponseFactory { private readonly Dictionary _requestHandlerTypes; public RequestResponseFactory() { _requestHandlerTypes = typeof(RequestResponseFactory).Assembly.GetTypes() .Where(t => !t.IsAbstract) .Select(t => new { HandlerType = t, RequestType = GetHandledRequestType(t) }) .Where(x => x.RequestType != null) .ToDictionary( x => x.RequestType, x => x.HandlerType ); } private static Type GetHandledRequestType(Type type) { var handlerInterface = type.GetInterfaces() .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IRequestHandler<,>)); return handlerInterface == null ? null : handlerInterface.GetGenericArguments()[0]; } public TResponse ProcessRequest(TRequest request) where TRequest : IRequestData { if (!_requestHandlerTypes.ContainsKey(typeof(TRequest))) throw new ApplicationException("No handler registered for type: " + typeof(TRequest).FullName); var handlerType = _requestHandlerTypes[typeof(TRequest)]; var handler = (IRequestHandler)Activator.CreateInstance(handlerType); return handler.ProcessRequest(request); } } public class CustomerRequestHandler : IRequestHandler { public CustomerResponse ProcessRequest(CustomerRequest request) { return new CustomerResponse { Success = true }; } } public class BillRequestHandler : IRequestHandler { public BillResponse ProcessRequest(BillRequest request) { return new BillResponse { Success = false }; } }