6

我正在尝试为我正在编写的一对 Windows 服务设置 RabbitMQ,以便以快速可靠的方式促进它们之间的通信。但是,我在尝试设置主要的 Windows 服务引擎时遇到了问题,这些引擎需要建立与 RabbitMQ 服务器的连接才能完成它们的工作。

基本上,ConnectionFactoryRabbitMQ 的 .NET 客户端中的对象不是抽象的,也没有实现任何接口。我看不到使用像 StructureMap 这样的 IoC 容器来注入此类的明显方法。甚至文档中的代码示例也只是明目张胆地展示了new它,如下所示:

 ConnectionFactory factory = new ConnectionFactory();
 factory.Uri = "amqp://user:pass@hostName:port/vhost";
 IConnection conn = factory.CreateConnection();

呈现给我的解决方案是将整个工厂推到服务的主要OnStartOnStop功能中,这真的很难测试,而且无论如何也没有太大的兴趣。然而,这给我留下了一个单一IConnection的服务,所以如果该连接以任何方式中断,服务将无法恢复,必须简单地退出。如果主引擎对工厂有可见性,它可以简单地产生一个新的连接并继续。但是除非我注入它,否则没有连接到现有服务器就无法测试主引擎!

我在这里有什么遗漏吗?我不考虑的任何其他选择?我怎样才能注入这个工厂,如果我不能,我怎样才能限制损害?

编辑:另外,作为事后的想法,如果有人很好地了解主要开发团队对这样的更改的接受程度,我很高兴对 RabbitMQ 的 .NET 客户端进行更改以在此实现一个接口。我很乐意做出贡献,但我最不想做的就是让我的程序在一些自定义版本的 RabbitMQ 上运行,从而首先消除使用第三方库的主要好处。

4

2 回答 2

7

RabbitMQ C# 客户端是一个低级纯 AMQP 实现,您可能希望将其包装在更高级别的抽象中,然后将其注册到您的 IoC 容器中。

EasyNetQ是对基本客户端的更高层次的抽象,实现了一个持久的 AMQP 连接,在连接丢失(通过网络问题或服务器反弹)后重新连接,并重建所有当前订阅。欢迎您使用任何您认为有用的代码。

简而言之,这是一个将连接管理包装在某种PersistentConnection类中的问题,然后使用一些代码注册每个订阅,以便在成功重新连接后重建它们

我写了一篇关于连接 EasyNetQ、Windsor IoC 容器和 TopShelf 的博客文章。我已经成功地使用这种技术来构建基于 RabbitMQ 的 Windows 服务。

于 2012-11-02T11:45:32.770 回答
5

棘手的部分是根据文档 看起来ConnectionFactory它没有实现任何接口。

所以你真的只剩下实现自己的东西了,比如,

public interface IConnectionFactory
{
    ConnectionFactory Get();
    ConnectionFactory Get(string uri);
}

public class ConnectionFactoryCreator : IConnectionFactory
{
    public ConnectionFactory Get(
        string uri = "amqp://user:pass@hostName:port/vhost")
    {
        return new ConnectionFactory
        {
            Uri = uri
        };
    }
}

对于您最终使用它的课程,

public class RabbitMQUserClass
{
    public ConnectionFactory ConnectionFactory {get; private set;}
    public RabbitMQUserClass(IConnectionFactory connectionFactory)
    {
        ConnectionFactory = connectionFactory.Get();
    }
}
于 2012-11-01T16:35:27.670 回答