gpt4 book ai didi

c# - 改进这个通用请求响应模式

转载 作者:太空狗 更新时间:2023-10-29 20:21:07 27 4
gpt4 key购买 nike

最近我似乎在处理很多请求/响应的东西,我想创建一些通用的东西。

我有以下内容,但我不喜欢创建多个 ifs 语句,我想避免它们。

思路是这样的:

不管请求/响应如何处理它们。如何在我的通用请求处理程序中删除这些 if 语句?

代码

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;
}
}

最佳答案

您可以替换 GenericRequestHandler<TRequest, TResponse>专业课 IRequestHandler s 并让工厂通过反射跟踪所有可用的此类处理程序。

具体来说,这些可能是处理程序:

public class CustomerRequestHandler : IRequestHandler<CustomerRequest, CustomerResponse>
{
public CustomerResponse ProcessRequest(CustomerRequest request)
{
return new CustomerResponse { Success = true };
}
}

public class BillRequestHandler : IRequestHandler<BillRequest, BillResponse>
{
public BillResponse ProcessRequest(BillRequest request)
{
return new BillResponse { Success = false };
}
}

现在,工厂不只是将调用转发给包含 if 的通用处理程序丑陋,会做以下事情:

  • 通过扫描当前程序集(可能还有其他程序集)以查找实现 IRequestHandler<TRequest, TResponse> 的类型来初始化自身。
  • 将构建处理程序类型的字典,其中键是 TRequest类型,值为处理程序类型
  • 对于任何传入的请求,它会检查处理程序列表以查看是否可以处理该特定类型,并且:
    • 将工作委托(delegate)给可用的处理程序
    • 如果找不到合适的处理程序则抛出异常

这是工厂类的一个可能实现:

class RequestResponseFactory : IRequestResponseFactory
{
private readonly Dictionary<Type, Type> _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, TResponse>(TRequest request) where TRequest : IRequestData<TResponse>
{
if (!_requestHandlerTypes.ContainsKey(typeof(TRequest)))
throw new ApplicationException("No handler registered for type: " + typeof(TRequest).FullName);

var handlerType = _requestHandlerTypes[typeof(TRequest)];

var handler = (IRequestHandler<TRequest, TResponse>)Activator.CreateInstance(handlerType);

return handler.ProcessRequest(request);
}
}

完整程序和工作示例可在 http://ideone.com/TxRnEi 获得。 .

输出与原始程序的输出相同,但现在该程序允许您添加新类型的请求和新类型的处理程序,并且能够在运行时动态使用它们,而无需编写长if/case语句来指定何时应该使用它们。

关于c# - 改进这个通用请求响应模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13218230/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com