.NET 中带有 Unity IOC 容器的 RabbitMQ

RabbitMQ with Unity IOC Container in .NET

我将 Unity App Block 用作 WCF 项目服务层的 IOC 容器。使用 Unity.WCF 库将其插入到每个 WCF 服务中效果很好。

我最近将 RabbitMQ 引入了我的服务层,我目前正在使用 "using" 块来连接和添加到队列中。我不喜欢这样,但我希望使用 HierachicalLifetimeManager 来创建和销毁我与 RabbitMQ 的连接,因为我需要它们吗?这听起来正确吗?

我正在寻找这方面的样本,或者至少是关于最佳方法的一些指导? (例如,我是否应该封装连接并根据需要注入到每个服务中?我将如何封装 RabbitMQ 消费者等?)

对于 RabbitMQ,您希望您的 IConnection 一直被重新使用,您不希望它出现在 "using" 块中。这是我使用 Ninject 的 IOC 绑定,请注意 InSingletonScope,这就是您想要的。

    Bind<IConnection>()
        .ToMethod(ctx =>
                  {
                      var factory = new ConnectionFactory
                      {
                          Uri = ConfigurationManager.ConnectionStrings["RabbitMQ"].ConnectionString,
                          RequestedHeartbeat = 15
                          //every N seconds the server will send a heartbeat.  If the connection does not receive a heardbeat within
                          //N*2 then the connection is considered dead.
                          //suggested from http://public.hudl.com/bits/archives/2013/11/11/c-rabbitmq-happy-servers/
                      };

                      var con = new AutorecoveringConnection(factory);
                      con.init();
                      return con;
                  })
        .InSingletonScope();

我建议将 IConnection 注册为单例。

要在 Unity 中将 IConnection 注册为单例,您可以使用 ContainerControlledLifetimeManager,例如

var connectionFactory = new ConnectionFactory
{
    // Configure the connection factory
};
unityContainer.RegisterInstance(connectionFactory);

unityContainer.RegisterType<IConnection, AutorecoveringConnection>(new ContainerControlledLifetimeManager(),
    new InjectionMethod("init"));

AutorecoveringConnection 实例在第一次解析后将保持活动状态,直到拥有的 UnityContainer 被处置。

因为我们用Unity注册了ConnectionFactory,这会自动注入到AutorecoveringConnection的构造函数中。 InjectionMethod 确保第一次解析 AutorecoveringConnection 时,调用 init 方法。

关于您是否应该从您的服务中抽象出 RabbitMQ 的问题,我的回答是肯定的,但我不会简单地创建一个 IMessageQueue 抽象。想想你使用消息队列的目的是什么,是为了推送状态吗?如果是这样,请使用 IStatusNotifier 接口和 RabbitMQ 的具体实现。如果要获取更新,请使用 IUpdateSource 接口和 RabbitMQ 的具体实现。你可以看到我要去哪里。

如果您为 Message Queue 创建抽象,则您将自己限制为只能在所有 Message Queue 实现中使用的功能。通过为不同的 Message Queue 实现使用不同的 IStatusNotifier 实现,您可以利用不同技术独有的功能,同时在将来使用完全不同的技术时保持灵活性(例如写入 SQL数据库或输出到控制台)。