これは、ネットワーク上のメッセージの形式と、それらを逆シリアル化する方法によって異なります。私はこのようなことをします(VB.NETを使用していないため、例はC#にありますが、変換は簡単なはずです)。
各コマンドはインターフェイスを実装し、いくつかの実装クラスICommand
から派生します。各コマンド タイプに固有の抽象プロパティを定義します (定数も使用できます)。この ID はネットワーク上のメッセージ ヘッダーの一部でもあるため、デバイスから送信されたコマンドを知ることができます。CommandBase
CommandBase
MessageId
デバイスからメッセージ ID を取得します。
int msgId = ... // what came from the device
Type cmdType = GetTypeForMessage(msgId); // get the corresponding implementation
ICommand cmd = (Command)Activator.CreateInstance(cmdType); // crate an instance
cmd.Deserialize(buffer); // or whatever way you do the serialization
cmd.Execute(); // run the command
以前に設定したマップから正しいタイプを取得します。
Type GetTypeForMessage(int msgId) {
// m_commandMap is Dictionary<int, Type>
return m_commandMap[msgId];
}
残りの問題は、セットアップ方法m_commandMap
です。1 つの方法は、あるクラスから派生するすべてのクラスを自動的に登録することCommandBase
です。起動時に次のようにします。
// find all types in this assembly
Assembly assembly = Assembly.GetExecutingAssembly();
foreach (var type in assembly.GetTypes()) {
if(typeof(CommandBase).IsAssignableFrom(type)) { // which derive from CommandBase
CommandBase cmd = (CommandBase) Activator.CreateInstance(type);
m_commandMap[cmd.MessageId] = type;
// I would make MessageId a static constant on class and read it
// using reflection, so I don't have to instantiate an object
}
}
新しいコマンドを実装する必要がある場合は、それを定義するだけです。
class NewCommand : CommandBase {
public override int MessageId { get { return 1234; } }
// or preferably: public const int MessageId = 1234;
// the rest of the command: ...
}
対応する ID がデバイスから取得された場合、起動時に自動的に登録され、逆シリアル化に使用されます。