fork(7) download
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. internal class Program
  6. {
  7. public static void Main()
  8. {
  9. IRequestResponseFactory factory = new RequestResponseFactory();
  10.  
  11. var customerRequest = new CustomerRequest { Name = "Joe", Surname = "Bloggs" };
  12. var customerResponse = factory.ProcessRequest<CustomerRequest, CustomerResponse>(customerRequest);
  13.  
  14. var billRequest = new BillRequest { Amount = 100m };
  15. var billResponse = factory.ProcessRequest<BillRequest, BillResponse>(billRequest);
  16.  
  17. Console.WriteLine(billResponse.Success);
  18. Console.WriteLine(customerResponse.Success);
  19. Console.ReadKey();
  20. }
  21. }
  22.  
  23.  
  24. public class CustomerRequest : IRequestData<CustomerResponse>
  25. {
  26. public string Name { get; set; }
  27. public string Surname { get; set; }
  28. }
  29.  
  30. public class CustomerResponse
  31. {
  32. public bool Success { get; set; }
  33. }
  34. public class BillRequest : IRequestData<BillResponse>
  35. {
  36. public decimal Amount { get; set; }
  37. }
  38. public class BillResponse
  39. {
  40. public bool Success { get; set; }
  41. }
  42. public interface IRequestData<TResponse>
  43. {
  44. }
  45.  
  46. public interface IRequestHandler<TRequest, TResponse> where TRequest : IRequestData<TResponse>
  47. {
  48. TResponse ProcessRequest(TRequest request);
  49. }
  50.  
  51. public interface IRequestResponseFactory
  52. {
  53. TResponse ProcessRequest<TRequest, TResponse>(TRequest request) where TRequest : IRequestData<TResponse>;
  54. }
  55.  
  56.  
  57. class RequestResponseFactory : IRequestResponseFactory
  58. {
  59. private readonly Dictionary<Type, Type> _requestHandlerTypes;
  60.  
  61. public RequestResponseFactory()
  62. {
  63. _requestHandlerTypes =
  64. typeof(RequestResponseFactory).Assembly.GetTypes()
  65. .Where(t => !t.IsAbstract)
  66. .Select(t => new
  67. {
  68. HandlerType = t,
  69. RequestType = GetHandledRequestType(t)
  70. })
  71. .Where(x => x.RequestType != null)
  72. .ToDictionary(
  73. x => x.RequestType,
  74. x => x.HandlerType
  75. );
  76. }
  77.  
  78. private static Type GetHandledRequestType(Type type)
  79. {
  80. var handlerInterface = type.GetInterfaces()
  81. .FirstOrDefault(i =>
  82. i.IsGenericType &&
  83. i.GetGenericTypeDefinition() == typeof(IRequestHandler<,>));
  84.  
  85. return handlerInterface == null ? null : handlerInterface.GetGenericArguments()[0];
  86. }
  87.  
  88. public TResponse ProcessRequest<TRequest, TResponse>(TRequest request) where TRequest : IRequestData<TResponse>
  89. {
  90. if (!_requestHandlerTypes.ContainsKey(typeof(TRequest)))
  91. throw new ApplicationException("No handler registered for type: " + typeof(TRequest).FullName);
  92.  
  93. var handlerType = _requestHandlerTypes[typeof(TRequest)];
  94.  
  95. var handler = (IRequestHandler<TRequest, TResponse>)Activator.CreateInstance(handlerType);
  96.  
  97. return handler.ProcessRequest(request);
  98. }
  99. }
  100.  
  101.  
  102. public class CustomerRequestHandler : IRequestHandler<CustomerRequest, CustomerResponse>
  103. {
  104. public CustomerResponse ProcessRequest(CustomerRequest request)
  105. {
  106. return new CustomerResponse { Success = true };
  107. }
  108. }
  109.  
  110. public class BillRequestHandler : IRequestHandler<BillRequest, BillResponse>
  111. {
  112. public BillResponse ProcessRequest(BillRequest request)
  113. {
  114. return new BillResponse { Success = false };
  115. }
  116. }
  117.  
Success #stdin #stdout 0.05s 38224KB
stdin
stdout
False
True