C# Quickfix/n,提取消息类型的最有效方法?
Quickfix/n 1.4中提取此处定义的消息类型的最有效方法是什么: 我目前使用C# Quickfix/n,提取消息类型的最有效方法?,c#,quickfix,fix-protocol,C#,Quickfix,Fix Protocol,Quickfix/n 1.4中提取此处定义的消息类型的最有效方法是什么: 我目前使用var msgType=Message.GetMsgType(Message.ToString())这将导致登录消息为“A”。有更好的办法吗?我试图在ToAdmin(…)中确定消息类型,以便捕获传出的登录请求消息,以便添加用户名和密码 我很想通过MessageCracker来实现,但到目前为止,我还没有找到一种方法来实现捕获所有剩余的消息类型,以防我没有实现所有OnMessage重载。(请参阅相关问题:) 谢谢在
var msgType=Message.GetMsgType(Message.ToString())代码>这将导致登录消息为“A”。有更好的办法吗?我试图在ToAdmin(…)
中确定消息类型,以便捕获传出的登录请求消息,以便添加用户名和密码
我很想通过MessageCracker来实现,但到目前为止,我还没有找到一种方法来实现捕获所有剩余的消息类型,以防我没有实现所有OnMessage重载。(请参阅相关问题:)
谢谢在这种情况下,您可以在管理员内部执行此操作:
var logonMessage = msg as Logon;
if (logonMessage != null)
{
//Treat the logon message as you want
}
或者使用另一个答案中解释的MessageCracker
希望有帮助。不是你的标题问题,而是其中的关键部分:
我试图确定ToAdmin(…)中的消息类型,以便捕获传出的登录请求消息,以便添加用户名和密码
下面是一组代码,几乎可以将其固定住():
这里是另一种方法,使用我在另一篇文章中提到的想法。实际上,将Crack方法分为两种方法并使用OnMessageTo和OnMessageFrom处理程序非常简单。上面的helper类的修改实现知道消息的方向,但肯定可以改进
在您的应用程序中,实现如下(不是完整的代码):
以及修改后的MessageCracker:
using System;
using System.Collections.Generic;
using System.Reflection;
namespace QuickFix
{
/// <summary>
/// Helper class for delegating message types for various FIX versions to
/// type-safe OnMessage methods, supports handling of incoming and outgoing messages separatelly
/// </summary>
public abstract class DirectedMessageCracker
{
private readonly Dictionary<Type, MethodInfo> _toHandlerMethods = new Dictionary<Type, MethodInfo>();
private readonly Dictionary<Type, MethodInfo> _fromHandlerMethods = new Dictionary<Type, MethodInfo>();
protected DirectedMessageCracker()
{
Initialize(this);
}
private void Initialize(Object messageHandler)
{
var handlerType = messageHandler.GetType();
var methods = handlerType.GetMethods();
foreach (var m in methods)
{
if (IsToHandlerMethod(m))
_toHandlerMethods[m.GetParameters()[0].ParameterType] = m;
else if (IsFromHandlerMethod(m))
_fromHandlerMethods[m.GetParameters()[0].ParameterType] = m;
}
}
static public bool IsToHandlerMethod(MethodInfo m)
{
return IsHandlerMethod("OnMessageTo", m);
}
static public bool IsFromHandlerMethod(MethodInfo m)
{
return IsHandlerMethod("OnMessageFrom", m);
}
static public bool IsHandlerMethod(string searchMethodName, MethodInfo m)
{
return (m.IsPublic
&& m.Name.StartsWith(searchMethodName)
&& m.GetParameters().Length == 2
&& m.GetParameters()[0].ParameterType.IsSubclassOf(typeof(Message))
&& typeof(SessionID).IsAssignableFrom(m.GetParameters()[1].ParameterType)
&& m.ReturnType == typeof(void));
}
/// <summary>
/// Process ("crack") a FIX message and call the registered handlers for that type, if any
/// </summary>
/// <param name="handlerMethods"></param>
/// <param name="message"></param>
/// <param name="sessionID"></param>
private void Crack(IDictionary<Type, MethodInfo> handlerMethods, Message message, SessionID sessionID)
{
var messageType = message.GetType();
MethodInfo handler;
if (handlerMethods.TryGetValue(messageType, out handler))
handler.Invoke(this, new object[] { message, sessionID });
else
throw new UnsupportedMessageType();
}
/// <summary>
/// Process ("crack") an INCOMING FIX message and call the registered handlers for that type, if any
/// </summary>
/// <param name="message"></param>
/// <param name="sessionID"></param>
public void CrackFrom(Message message, SessionID sessionID)
{
Crack(_fromHandlerMethods, message, sessionID);
}
/// <summary>
/// Process ("crack") an OUTGOING FIX message and call the registered handlers for that type, if any
/// </summary>
/// <param name="message"></param>
/// <param name="sessionID"></param>
public void CrackTo(Message message, SessionID sessionID)
{
Crack(_toHandlerMethods, message, sessionID);
}
}
}
使用系统;
使用System.Collections.Generic;
运用系统反思;
命名空间快速修复
{
///
///帮助器类,用于将各种修复版本的消息类型委派给
///类型安全的OnMessage方法,支持分别处理传入和传出消息
///
公共抽象类DirectedMessageCracker
{
私有只读字典_toHandlerMethods=新字典();
私有只读词典_fromHandlerMethods=新词典();
受保护的DirectedMessageCracker()
{
初始化(这个);
}
私有void初始化(对象messageHandler)
{
var handlerType=messageHandler.GetType();
var methods=handlerType.GetMethods();
foreach(方法中的var m)
{
if(IsToHandlerMethod(m))
_toHandlerMethods[m.GetParameters()[0].ParameterType]=m;
else if(IsFromHandlerMethod(m))
_fromHandlerMethods[m.GetParameters()[0].ParameterType]=m;
}
}
静态公共布尔IsToHandlerMethod(MethodInfo m)
{
返回IsHandlerMethod(“OnMessageTo”,m);
}
静态公共bool IsFromHandlerMethod(MethodInfo m)
{
返回IsHandlerMethod(“OnMessageFrom”,m);
}
静态公共bool IsHandlerMethod(字符串searchMethodName,MethodInfo m)
{
返回(m.IsPublic)
&&m.Name.StartsWith(searchMethodName)
&&m.GetParameters().Length==2
&&m.GetParameters()[0]。ParameterType.IsubClassOf(消息类型))
&&typeof(SessionID).IsAssignableFrom(m.GetParameters()[1].ParameterType)
&&m.ReturnType==typeof(void));
}
///
///处理(“破解”)修复消息并调用该类型的已注册处理程序(如果有)
///
///
///
///
私有void破解(IDictionary handlerMethods、Message、SessionID SessionID)
{
var messageType=message.GetType();
方法信息处理程序;
if(handlerMethods.TryGetValue(messageType,out处理程序))
调用(这个,新对象[]{message,sessionID});
其他的
抛出新的不受支持的消息类型();
}
///
///处理(“破解”)传入的修复消息,并调用该类型的已注册处理程序(如果有)
///
///
///
public void CrackFrom(消息消息,SessionID SessionID)
{
裂纹(来自HandlerMethods、message、sessionID);
}
///
///处理(“破解”)传出的修复消息,并调用该类型的已注册处理程序(如果有)
///
///
///
public void CrackTo(消息消息,SessionID SessionID)
{
裂纹(_-toHandlerMethods、message、sessionID);
}
}
}
如果您不想通过删除throw new UnsupportedMessageType(),来实现所有可能的消息处理程序,您也可以跳过破解而不是抛出异常代码>来自裂纹方法
另一个想法是拆分破解管理员/应用程序消息。这是过早的优化。先让它工作。推迟绩效调查,直到你知道你需要它。对不起,我的评论太直截了当了。我想说的是,如果您有性能问题,这个小字符串解析问题不可能是您的主要原因。在有证据证明这是个问题之前,不要担心优化问题。这与性能完全无关。我需要检查发送的消息是否是登录,以便添加用户名和密码。我想我将您使用的“高效”解释为性能。我的错。不用担心,也许“高效”这个词有误导性。谢谢你的回答。正是我想要的。我不知道Tag类。非常感谢。谢谢,但我觉得格兰特的回答稍微优雅一点。谢谢你+1非常感谢这个想法。但是,我搁置了使用MessageCracker的整个想法,因为构建器目前似乎无法为添加的xml数据字典自定义消息类型创建代码。没有它,我也不能使用MessageCracker,而只能自己构建消息。仍然
public class MyFixApplication: DirectedMessageCracker, Application
{
...
public void FromAdmin(Message msg, SessionID sessionId)
{
CrackFrom(msg, sessionId);
}
public void ToAdmin(Message msg, SessionID sessionId)
{
CrackTo(msg, sessionId);
}
public void OnMessageTo(Logon msg, SessionID sessionId)
{
//Treat the outgoing message, set user, password, etc
}
public void OnMessageFrom(Allocation msg, SessionID sessionId)
{
//Treat the incoming Allocation message
}
...and so on
using System;
using System.Collections.Generic;
using System.Reflection;
namespace QuickFix
{
/// <summary>
/// Helper class for delegating message types for various FIX versions to
/// type-safe OnMessage methods, supports handling of incoming and outgoing messages separatelly
/// </summary>
public abstract class DirectedMessageCracker
{
private readonly Dictionary<Type, MethodInfo> _toHandlerMethods = new Dictionary<Type, MethodInfo>();
private readonly Dictionary<Type, MethodInfo> _fromHandlerMethods = new Dictionary<Type, MethodInfo>();
protected DirectedMessageCracker()
{
Initialize(this);
}
private void Initialize(Object messageHandler)
{
var handlerType = messageHandler.GetType();
var methods = handlerType.GetMethods();
foreach (var m in methods)
{
if (IsToHandlerMethod(m))
_toHandlerMethods[m.GetParameters()[0].ParameterType] = m;
else if (IsFromHandlerMethod(m))
_fromHandlerMethods[m.GetParameters()[0].ParameterType] = m;
}
}
static public bool IsToHandlerMethod(MethodInfo m)
{
return IsHandlerMethod("OnMessageTo", m);
}
static public bool IsFromHandlerMethod(MethodInfo m)
{
return IsHandlerMethod("OnMessageFrom", m);
}
static public bool IsHandlerMethod(string searchMethodName, MethodInfo m)
{
return (m.IsPublic
&& m.Name.StartsWith(searchMethodName)
&& m.GetParameters().Length == 2
&& m.GetParameters()[0].ParameterType.IsSubclassOf(typeof(Message))
&& typeof(SessionID).IsAssignableFrom(m.GetParameters()[1].ParameterType)
&& m.ReturnType == typeof(void));
}
/// <summary>
/// Process ("crack") a FIX message and call the registered handlers for that type, if any
/// </summary>
/// <param name="handlerMethods"></param>
/// <param name="message"></param>
/// <param name="sessionID"></param>
private void Crack(IDictionary<Type, MethodInfo> handlerMethods, Message message, SessionID sessionID)
{
var messageType = message.GetType();
MethodInfo handler;
if (handlerMethods.TryGetValue(messageType, out handler))
handler.Invoke(this, new object[] { message, sessionID });
else
throw new UnsupportedMessageType();
}
/// <summary>
/// Process ("crack") an INCOMING FIX message and call the registered handlers for that type, if any
/// </summary>
/// <param name="message"></param>
/// <param name="sessionID"></param>
public void CrackFrom(Message message, SessionID sessionID)
{
Crack(_fromHandlerMethods, message, sessionID);
}
/// <summary>
/// Process ("crack") an OUTGOING FIX message and call the registered handlers for that type, if any
/// </summary>
/// <param name="message"></param>
/// <param name="sessionID"></param>
public void CrackTo(Message message, SessionID sessionID)
{
Crack(_toHandlerMethods, message, sessionID);
}
}
}