C# 如何正确设计通用的;“请求调度程序”;在C中#
我有一个对象“Receiver”,它接收/反序列化许多不同类型的请求 然后,我希望这个接收者使用一个“Dispatcher”对象,该对象将根据传入请求的类型将请求对象分派到正确的请求处理程序对象(以前在Dispatcher上注册)。当然,只有在运行时才知道请求的类型,而不是在编译时(这太容易了;) 这里有一些代码来澄清一些事情 我有一个用于请求类型的标记接口:C# 如何正确设计通用的;“请求调度程序”;在C中#,c#,generics,requestdispatcher,C#,Generics,Requestdispatcher,我有一个对象“Receiver”,它接收/反序列化许多不同类型的请求 然后,我希望这个接收者使用一个“Dispatcher”对象,该对象将根据传入请求的类型将请求对象分派到正确的请求处理程序对象(以前在Dispatcher上注册)。当然,只有在运行时才知道请求的类型,而不是在编译时(这太容易了;) 这里有一些代码来澄清一些事情 我有一个用于请求类型的标记接口: public interface IRequest {} 然后是一个虚拟请求类型: public class DummyRequest
public interface IRequest {}
然后是一个虚拟请求类型:
public class DummyRequest : IRequest {}
这是请求处理程序对请求类型T使用的通用接口
public interface IRequestHandler<in T> where T : IRequest
{
void HandleRequest(T request);
}
当然,只有在编译时已知请求类型时,它才起作用,但在我的上下文中,接收方将请求作为对象类型接收,例如:
// Here ReceiveMessage is not generic and therefore returns object type
// (even if type is DummyRequest, it's just being returned as an object,
// i.e : "request is DummyRequest" returns true)
// signature of ReceiveMessage is "object ReceiveMessage()"
var request = ReceiveMessage();
我不能这样打电话给调度员
dispatcher.Dispatch(request);
我无法找到一种方法在不失去类型安全性的情况下解决这个问题(例如,不将HandlerRequest签名更改为使用对象的非泛型签名),我不希望丢失它
我希望我的问题是明确的和有意义的。。。也许没有真正的方法,我不知道
在谷歌搜索“请求调度程序C#”时没有发现任何有趣的东西。也许这种“模式”是用另一个名字命名的,但我把它称为请求调度器是有意义的
这样做的最终目的是能够处理新的请求类型,只需为特定的请求类型创建一个新的请求处理程序,并在调度程序上注册它,而无需更改接收方或调度程序的代码。
谢谢 您无法摆脱这样一个事实,即直到运行时才知道对象类型,因此您需要一个能够处理该问题的设计。
你应该看看工厂的模式。如果你用谷歌搜索,你会发现大量的例子。但本质上,您必须在运行时确定代码中对象的类型,并确定要实例化的对象类型。这可以采取使用反射的形式,也可以只是工厂方法内部的一个switch语句。您可以做的是实现抽象工厂模式(合并泛型),非常简单地概括一下,它可以如下所示
public interface IRequest
{
void Dispatch();
}
其中,您将使用以下类来获得在运行时使用的正确“策略”
public static class DispatchStrategyfactory
{
public static void Dispatch<T>(T instance) where T : IRequest
{
instance.Dispatch();
}
}
这将使您能够做您需要的事情。有关策略/[Abstract]工厂模式的更多信息,请参阅。我希望我没有错过这里的要点
我希望这有帮助
// Here ReceiveMessage is not generic and therefore returns object type
// (even if type is DummyRequest, it's just being returned as an object,
// i.e : "request is DummyRequest" returns true)
// signature of ReceiveMessage is "object ReceiveMessage()"
var request = ReceiveMessage();
dispatcher.Dispatch(request);
public interface IRequest
{
void Dispatch();
}
public static class DispatchStrategyfactory
{
public static void Dispatch<T>(T instance) where T : IRequest
{
instance.Dispatch();
}
}
public static TestDispatcher : IRequest
{
public void Dispatch()
{
// Do stuff.
}
}