Here’s something that bit me, maybe you can add a note to the docs on the wiki (https://github.com/ServiceStack/ServiceStack/wiki/Messaging)
The example looks like this:
public class AppHost : AppSelfHostBase
{
public override void Configure(Container container)
{
//Register to use a Rabbit MQ Server
container.Register<IMessageService>(c => new RabbitMqServer());
var mqServer = container.Resolve<IMessageService>();
//Register message handlers here...
mqServer.RegisterHandler<HandleExampleMessageRequest>(ServiceController.ExecuteMessage);
//Start the Rabbit MQ Server listening for incoming MQ Requests
mqServer.Start();
}
}
However, if your message handler calls a service, which publishes a new message, you could get a NullReferenceException on the first message or two (depending how busy the queue is).
public class ExampleService : Service
{
public void Post(HandleExampleMessageRequest request)
{
//Do stuff here
//This throws NRE on the first call if the MQ service is started in AppHost.Configure
PublishMessage(new DoNextStep
{
Id = request.Id
});
}
}
Stack trace
System.NullReferenceException: Object reference not set to an instance of an object.
at ServiceStack.ServiceStackHost.GetMessageProducer(IRequest req)
at ServiceStack.Service.get_MessageProducer()
at ServiceStack.Service.PublishMessage[T](T message)
at ServiceInterface.ExampleService.Post(HandleExampleMessageRequest request) in ExampleService.cs:line 10
at lambda_method(Closure , Object , Object )
at ServiceStack.Host.ServiceExec`1.<>c__DisplayClass6.<CreateExecFn>b__5(Object service, Object request)
at ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object instance, TRequest requestDto)
This is because the IMessageFactory (which is automatically registered in ServiceStackHost.OnAfterInit) is not available until the AppHost has completed initializing.
To avoid this problem, the MQ service should be started in an AfterInitCallback.
public class AppHost : AppSelfHostBase
{
public AppHost()
: base("My Services", new[] { typeof(HandleExampleMessageRequest).Assembly })
{
AfterInitCallbacks.Add(StartMqServer);
}
private void StartMqServer(IAppHost appHost)
{
//Start MQ consumers
appHost.GetContainer().Resolve<IMessageService>().Start();
}
}