构建我的消息处理程序的正确方法是什么,以便它们可以移出appHost?

时间:2014-10-24 12:24:00

标签: c# servicestack rabbitmq

给出了我的RabbitMQ请求和响应消息的以下代码:

public class AppHost : ServiceStackHost
{
    public AppHost()
        : base("LO.Leads.Processor", typeof(LeadService).Assembly) { }

    public override void Configure(Container container)
    {
        //DataAccess

        //RabbitMQ
        container.Register<IMessageService>(c => new RabbitMqServer("cdev-9010.example.com", "test", "test") 
        {
            AutoReconnect = true,
            DisablePriorityQueues = true,

        }); 
        var mqServer = container.Resolve<IMessageService>();
        var messageHandlers = new MessageHandlers(); // Is there a better way than newing up an instance?
        mqServer.RegisterHandler<LeadInformation>(messageHandlers.OnProcessLeadInformation, messageHandlers.OnExceptionLeadInformation);
        mqServer.Start();       
    }
}


public class MessageHandlers
{
    readonly ILog _log = LogManager.GetLogger(typeof(MessageHandlers));

    public object OnProcessLeadInformation(IMessage<LeadInformation> request)
    {

        _log.DebugFormat("Request message received {0}", request.Id);

        try
        {
            // Log to the database

            // Run rules against lead

            // Log response to database

            // return response

        }
        catch (Exception exception)
        {
            _log.Error(request, exception);
        }
        return new LeadInformationResponse();
    }

    public void OnExceptionLeadInformation(IMessage<LeadInformation> request, Exception exception)
    {
        _log.Error(request, exception);
    }

}

大多数ServiceStack文档都显示了一个匿名方法在线使用的示例,但这会迅速使apphost文件膨胀,我希望将此代码移到服务接口项目附近。无论如何都要定义委托,而不必实例化&#34; MessageHandlers&#34;类?

2015年5月29日更新

我花了几个月的时间来思考这个问题,我想补充一点,我从未实施过更改以将方法调用从匿名转移到委托。

但是现在是时候提交了,为此我已经提出了“模板”#39;与RegisterHandeler方法的签名匹配的类,代码如下。

public static class HelloHandler
{
    private static ILog _log = LogManager.GetLogger("logger");

    public static Func<IMessage<ServiceModel.Hello>, object> ProcessMessageFn
    {
        get { return OnProcessMessage; }
    }

    public static Action<IMessageHandler, IMessage<ServiceModel.Hello>, Exception> ProcessExpectionFn
    {
        get { return OnProcessExpection; }
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="message"></param>
    /// <returns></returns>
    private static object OnProcessMessage(IMessage<ServiceModel.Hello> message)
    {

        return message;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="handler"></param>
    /// <param name="message"></param>
    /// <param name="exception"></param>
    private static void OnProcessExpection(IMessageHandler handler, IMessage<ServiceModel.Hello> message, Exception exception)
    {
        /*
            public interface IMessageHandler
            {
                Type MessageType { get; }

                IMessageQueueClient MqClient { get; }

                void Process(IMessageQueueClient mqClient);

                int ProcessQueue(IMessageQueueClient mqClient, string queueName, Func<bool> doNext = null);

                void ProcessMessage(IMessageQueueClient mqClient, object mqResponse);

                IMessageHandlerStats GetStats();
            }
         */


        /*
            public interface IMessage<T> : IMessage, IHasId<Guid>
            {
                T GetBody();
            }
         */


        /*
            Exception
         */


    }
}

我开始更倾向于这个设计,但这让我质疑

的用法
  

OnProcessExpection

方法。传入的第一个参数是什么?什么时候这是相关的,我该怎么办呢?界面确实有GetStats方法,这可能对诊断和问题有益,但我只是在猜测。

谢谢你, 斯蒂芬

0 个答案:

没有答案