I have a handler that looks like this:
public class CreateNewUserHandler :
Saga<UncorroboratedCreateNewUser>,
IAmStartedByMessages<CreateNewUser>,
IHandleMessages<FoundUser>
{
[Dependency]
public IBus Bus { get; set; }
public override void ConfigureHowToFindSaga()
{
ConfigureMapping<CreateNewUser>(saga => saga.CorrelationId, req => req.CorrelationId);
ConfigureMapping<FoundUser>(saga => saga.CorrelationId, foundUser => foundUser.CorrelationId); //CorrelationId is of type Guid here
}
public void Handle(CreateNewUser message)
{
Mapper.DynamicMap(message, Data, typeof(CreateNewUser), typeof(UncorroboratedCreateNewUser));
Data.CorrelationId = message.CorrelationId;
Bus.Send(new FindUserByUserName { CorrelationId = Data.CorrelationId, UserName = message.UserName });
}
public void Handle(FoundUser message)
{
//**THIS BLOCK WAS NEVER HIT**
}
}
Now the other handler that is supposed to reply with FoundUser
is like this:
public class FindUserByUserNameHandler : IMessageHandler<FindUserByUserName>
{
private readonly UserRepository _userRepository;
public IBus Bus { get; set; }
public FindUserByUserNameHandler(UserRepository userRepository)
{
_userRepository = userRepository;
}
public void Handle(FindUserByUserName message)
{
var foundUser = _userRepository.FindByUserName(message.UserName);
FoundUser result = Bus.CreateInstance<FoundUser>( _ => _.CorrelationId = message.CorrelationId);
if (foundUser != null)
{
result = Mapper.DynamicMap<FoundUser>(foundUser);
result.IsUserFound = true;
}
else
{
result.
AuthenticationUserName = message.UserName;
result.IsUserFound = false;
}
Bus.Reply(result);
}
}
In Debugging, I have been able to trace message getting into CreateNewUser => FindUserByName => Reply, and eyeballing the trace logging it even looks like the message made it back to the originating queue.
However the method void Handle(FoundUser message)
was never called! I have lost a night sleep wrecking my brain and combing the internet for clues as to where I might have dropped the ball. One other thing if CreateNewUserHandler, was to be turned into a regular handler (non-saga), the method above gets called!
These are the only clues I have to go on (and it's not much - I really wished the error made more sense)
2013-05-17 14:30:29,682 [Worker.18] WARN MyProject.Unicast.Transport.Transactional.TransactionalTransport [(null)] <(null)> - Failed raising 'transport message received' event for message with ID=377f1e49-06e2-465f-877a-9443828e8866 System.NullReferenceException: Object reference not set to an instance of an object. at NServiceBus.Unicast.UnicastBus.HandleTransportMessage(IBuilder childBuilder, TransportMessage msg) in c:\TeamCity\buildAgent\work\nsb.master_7\src\unicast\NServiceBus.Unicast\UnicastBus.cs:line 1331 at NServiceBus.Unicast.UnicastBus.TransportMessageReceived(Object sender, TransportMessageReceivedEventArgs e) in c:\TeamCity\buildAgent\work\nsb.master_7\src\unicast\NServiceBus.Unicast\UnicastBus.cs:line 1248 at System.EventHandler`1.Invoke(Object sender, TEventArgs e) at NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.OnTransportMessageReceived(TransportMessage msg) in c:\TeamCity\buildAgent\work\nsb.master_7\src\impl\unicast\transport\NServiceBus.Unicast.Transport.Transactional\TransactionalTransport.cs:line 480
And also
2013-05-17 14:30:29,591 [Worker.18] INFO NServiceBus.Sagas.Impl.SagaDispatcherFactory [(null)] <(null)> - Could not find a saga for the message type MyProject.Messages.FoundUser with id 377f1e49-06e2-465f-877a-9443828e8866. Going to invoke SagaNotFoundHandlers.
And just in case it's needed the configuration is:
NServiceBus.Configure.With(busAssemblies)
.Log4Net()
.License(Config.Default.NServiceBus_License)
.DefineEndpointName(endPointName)
.UnityBuilder(serviceBusDiConfiguration.Container)
.DontUseTransactions() //I don't know why this is needed, but doesn't seem to get very far otherwise.
.AzureConfigurationSource()
.AzureSagaPersister()
.AzureSubcriptionStorage()
.AzureDataBus()
.JsonSerializer()
.AzureServiceBusMessageQueue()
.UnicastBus()
.LoadMessageHandlers()
.CreateBus()
.Start();
BusConfiguration.Configurer.ConfigureComponent(uoWImplementer, DependencyLifecycle.InstancePerUnitOfWork); //For the custom unitOfWork
Please help!
=====================Message DTOs Below==========================
public class CreateNewUser : ICommand
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public Guid CorrelationId { get; set; }
}
public class FindUserByUserName : IMessage
{
public Guid CorrelationId { get; set; }
public string UserName { get; set; }
}
public class FoundUser: IMessage
{
public bool IsUserFound { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string AuthenticationUserName { get; set; }
public Guid CorrelationId { get; set; }
}
And the saga class iself:
public class UncorroboratedCreateNewUser : IContainSagaData
{
public virtual Guid Id { get; set; }
public virtual string Originator { get; set; }
public virtual string OriginalMessageId { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual string UserName { get; set; }
public virtual string Password { get; set; }
public virtual Guid CorrelationId { get; set; }
}