关于C#:NServiceBus传奇不起作用

NServiceBus saga not working

我有一个看起来像这样的处理程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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**
    }
}

现在应该用FoundUser答复的另一个处理程序是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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);
    }
}

在调试中,我已经能够跟踪进入CreateNewUser => FindUserByName => Reply的消息,并且跟踪跟踪记录日志,甚至看起来就像消息已将其返回到原始队列一样。

但是从未调用过方法void Handle(FoundUser message)!我失去了一个彻夜难眠的睡眠,打乱了我的大脑,并在互联网上寻找有关我可能丢球的线索。如果将CreateNewUserHandler转换为常规处理程序(非传奇),则另一件事就是调用上面的方法!

这些是我必须继续做的唯一线索(而且不多-我真的希望该错误更有意义)

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\
sb.master_7\\src\\unicast\
ServiceBus.Unicast\\UnicastBus.cs:line
1331 at NServiceBus.Unicast.UnicastBus.TransportMessageReceived(Object
sender, TransportMessageReceivedEventArgs e) in
c:\\TeamCity\\buildAgent\\work\
sb.master_7\\src\\unicast\
ServiceBus.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\
sb.master_7\\src\\impl\\unicast\\transport\
ServiceBus.Unicast.Transport.Transactional\\TransactionalTransport.cs:line
480

还有

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.

以防万一,需要的配置是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

请帮助!

======================下面的消息DTO ======================= ===

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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; }
}

和saga类iself:

1
2
3
4
5
6
7
8
9
10
11
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; }
}


有几件事让我惊讶。

首先,尝试在您的初始化代码中在Configure.With()之后和.CreateBus()之前调用.Sagas()。

此外,删除对saga的Bus依赖-NServiceBus具有在saga类上已定义的依赖。

删除对CreateNewUser的ConfigureMapping调用(除非您希望每个传奇都收到此消息的多个实例)。

最后,在saga数据的CorrelationID属性上放置一个[Unique]属性(以确保如果并行处理消息,则最终不会出现多个saga)。


我认为映射代码会覆盖CorrelationId

1
result = Mapper.DynamicMap<FoundUser>(foundUser);

CorrelationId最后分配