以前、SignalRのHUBについてチョット書いたことがあるけれど、見落としていたことがあったので、今更ながら情報を追加しておく(汗)
SignalRのHUBだが、クライアントへメッセージを渡すメソッドに関して、Interfaceを定義しておけば、nameofを使用して文字列ベタ打ちじゃなくても済むというようなことを書いたが、実はもっと、簡単な方法があった。(HUBに関してだけだけど・・・)
その方法とは、作成するHubのベースクラスをHubではなく、Hub<T>にすること。このTはインターフェイスを表す。例えば、以下のような感じ。
/// <summary>
/// Hub Methods(Called by Client)
/// </summary>
public interface IHubMethods {
Task LogOn(string UserName);
Task SendMessage(string UserName, string Message);
Task LogOff();
}
/// <summary>
/// Client Methods(Called by Hub)
/// </summary>
public interface IClientMethods {
Task ReceiveMessage(string UserName, string Message);
Task LogOnMessage(string UserName);
Task LogOffMessage(string UserName);
}
publc class MyHub : Hub<IClientMethods>, IHubMethods {
・・・
public async Task SendMessage(string UserName, string Message) {
// 普通なら、
// await Clients.All.SendAsync(nameof(IClientMethods.ReceieveMessage),UserName,Message);
// と書くのが普通だが、下記で上記と同様となる。(I/Fのデフォルト実装でもしているのかな?
// チョット気持ち悪いんだが・・・)
await Clients.All.ReceieveMessage(UserName,Message);
}
・・・
}
I/Fのデフォルト実装でも勝手にしているのか、I/Fに定義されたシグネチャで呼び出すとSendAsyncが呼ばれるようだ。私的には裏で何かしらやられるのはあまり好きでは無いが、確かにこれなら、メソッド名とパラメータを間違えることはないね。
SignalRを使うために結構MSのサイト見ていたつもりなのだけど、見落としていました・・・
※ちなみに、この方法を使うと、Clients.XXX.SendAsyncは使用不可となるので注意。