我有一个 ESB 。任何序列化消息都传输其自己的完全限定名称(即名称空间+类名)。每个消息都有一个具体的类型,它封装了要执行的特定逻辑 每次收到消息时,我都需要首先对其进行反序列化,这样我就可以执行其操作 - 更多,具体取决于具体类型 - 。
我需要一种在编译时或在应用程序初始化期间注册每个类的方法 使用.net,我会使用反射来扫描程序集并在初始化期间发现消息类型,但是如何在C ++中执行呢?
答案 0 :(得分:3)
C ++没有反射功能。我想你可以尝试扫描目标文件等,但没有可靠的方法来做到这一点(AFAIK);编译器可能完全消除或破坏某些东西。
基本上,对于序列化,您必须手动进行注册(半)。但是您可能会对序列化库感兴趣,这些库可以帮助解决诸如Boost Serialization等问题。
答案 1 :(得分:1)
由于C ++中没有反射,我建议使用外部脚本扫描所有相关类的源代码(如果使用空虚拟#defines在源代码中对它们进行注释,这很容易)并生成它注册码。
答案 2 :(得分:1)
我个人使用手动登记道路。如果您忘记注册...那么测试无论如何都不起作用。
您只需使用工厂,并实施一些标签调度。例如:
typedef void (*ActOnMessageType)(Message const&);
typedef std::map<std::string, ActOnMessageType> MessageDispatcherType;
static MessageDispatcherType& GetDispatcher() {
static MessageDispatcherType D; return D;
}
static bool RegisterMessageHandler(std::string name, ActOnMessageType func) {
return GetDispatcher().insert(std::make_pair(name, func)).second;
}
然后你就准备好了你的职能:
void ActOnFoo(Message const& m);
void ActOnBar(Message const& m);
注册他们:
bool const gRegisteredFoo = RegisterMessageHandler("Foo", ActOnFoo);
bool const gRegisteredBar = RegsiterMessageHandler("Bar", ActOnBar);
注意:我有效地使用了一个懒惰的初始化Singleton,以便允许解耦。也就是说,注册是在库加载期间完成的,因此每个Register...
调用都放在定义函数的文件中。与全局变量的一个区别在于,一旦初始化结束,调度映射实际上是常量。