MassTransit的ISendObserver没有观察到

时间:2016-07-21 16:31:16

标签: masstransit

我有一个消费者也在向公交车发布回复。我可以使用IReceiveObserver连接并在公交车上工作,但我无法运行ISendObserverIPublishObserver。我已经通过RabbitMQ管理控制台确认消息 正确发布。

class Program
{
    static BusHandle _BusHandle;

    static void Main(string[] args)
    {
        InitLogging();
        InitStructureMap();
        InitBus();

        System.Console.WriteLine("Starting processing, ENTER to stop...");
        System.Console.ReadLine();
        System.Console.WriteLine("See you later, alligator!");

        StopBus();
    }

    static void InitBus()
    {
        var busCtrl = ObjectFactory.Container.GetInstance<IBusControl>();
        var recObserver = ObjectFactory.Container.GetInstance<IReceiveObserver>();
        var sendObserver = ObjectFactory.Container.GetInstance<ISendObserver>();

        busCtrl.ConnectReceiveObserver(recObserver);
        busCtrl.ConnectSendObserver(sendObserver);

        _BusHandle = busCtrl.Start();
    }

    static void StopBus()
    {
        _BusHandle.Stop();
    }


    static void InitLogging()
    {
        XmlConfigurator.Configure();
        Log4NetLogger.Use();
    }

    static void InitStructureMap()
    {
        ObjectFactory.Initialize(x => {
            x.AddRegistry<MyTestConsoleRegistry>();
            x.AddRegistry<MyTestRegistry>();
        });
    }
}

public class MyTestConsoleRegistry : Registry
{
    public MyTestConsoleRegistry()
    {
        var rabbitURI = ConfigurationManager.AppSettings["rabbitMQHostUri"];
        var queueName = ConfigurationManager.AppSettings["massTransitQueue"];

        For<IBusControl>(new SingletonLifecycle())
            .Use("Configure IBusControl for MassTransit consumers with RabbitMQ transport", 
                ctx => Bus.Factory.CreateUsingRabbitMq(cfg => {
                    cfg.UseJsonSerializer();
                    cfg.PublisherConfirmation = true;

                    var host = cfg.Host(new Uri(rabbitURI), rabbitCfg => { });

                    cfg.ReceiveEndpoint(host, queueName, endpointCfg => {
                        endpointCfg.LoadFrom(ctx);
                    });
                })
            );

        For<IReceiveObserver>().Use<MassTransitObserver>();
        For<ISendObserver>().Use<MassTransitObserver>();

        // ...snip...
    }
}


public class MyTestRegistry : Registry
{
    public MyTestRegistry()
    {
        ForConcreteType<MyTestConsumer>();

        // ...snip...
    }
}

public class MassTransitObserver : IReceiveObserver, ISendObserver
{

    // Does nothing for now, just trying to wire it up...

    public Task ConsumeFault<T>(ConsumeContext<T> context, TimeSpan duration, string consumerType, Exception exception) where T : class
    {
        return Task.CompletedTask;
    }

    public Task PostConsume<T>(ConsumeContext<T> context, TimeSpan duration, string consumerType) where T : class
    {
        return Task.CompletedTask;
    }

    public Task PostReceive(ReceiveContext context)
    {
        return Task.CompletedTask;
    }

    public Task PreReceive(ReceiveContext context)
    {
        return Task.CompletedTask;
    }

    public Task ReceiveFault(ReceiveContext context, Exception exception)
    {
        return Task.CompletedTask;
    }

    public Task PreSend<T>(SendContext<T> context) where T : class
    {
        return Task.CompletedTask;
    }

    public Task PostSend<T>(SendContext<T> context) where T : class
    {
        return Task.CompletedTask;
    }

    public Task SendFault<T>(SendContext<T> context, Exception exception) where T : class
    {
        return Task.CompletedTask;
    }
}


public class MyTestConsumer : IConsumer<MyTestMessage>,
    // for testing only:
    IConsumer<MyTestResponse>
{
    readonly IDoSomething _DoSomething;

    public TestConsumer(IDoSomething doSomething)
    {
        _DoSomething = doSomething;
    }

    public Task Consume(ConsumeContext<MyTestResponse> context)
    {
        // For testing only...
        return Task.CompletedTask;
    }

    public async Task Consume(ConsumeContext<MyTestMessage> context)
    {
        var result = await _DoSomething(context.Message.Id);
        var resp = new MyTestResponseMessage(result);

        await context
            .Publish<MyTestResponse>(resp);
    }
}

鉴于此代码,IReceiveObserver方法将被调用,但ISendObserver方法不会被调用。

我是MassTransit的新手,我希望这可能是一个直截了当的问题。

编辑:使用NUnit和Moq的单元测试不使用StructureMap。我相信这恰当地说明了我所看到的。

[Test]
public void TestSendObserver()
{
    var bus = CreateBus();
    var busHandle = bus.Start();

    var sendObs = new Mock<ISendObserver>();

    sendObs.Setup(x => x.PreSend<TestMessage>(It.IsAny<SendContext<TestMessage>>()))
        .Returns(Task.FromResult(0))
        .Verifiable();

    sendObs.Setup(x => x.PostSend<TestMessage>(It.IsAny<SendContext<TestMessage>>()))
        .Returns(Task.FromResult(0))
        .Verifiable();

    using (bus.ConnectSendObserver(sendObs.Object)) {
        var pubTask = bus.Publish(new TestMessage { Message = "Some test message" });
        pubTask.Wait();
    }

    busHandle.Stop();

    // Fails, neither PreSend nor PostSend have been called
    sendObs.Verify(x => x.PreSend<TestMessage>(It.IsAny<SendContext<TestMessage>>()), Times.Once());
    sendObs.Verify(x => x.PostSend<TestMessage>(It.IsAny<SendContext<TestMessage>>()), Times.Once());
}

IBusControl CreateBus()
{
    return MassTransit.Bus.Factory.CreateUsingRabbitMq(x => {

        var host = x.Host(new Uri("rabbitmq://localhost/"), h => {
            h.Username("guest");
            h.Password("guest");
        });
    });
}

public class TestMessage
{
    public String Message { get; set; }
}

0 个答案:

没有答案