2014-09-05 43 views
1

我与传奇故事在画谜和我与NServiceBus工作的经验,你可以回复到佐贺的原创者给予更新,这样的事情:画谜相当于NServiceBus佐贺ReplyToOriginator

Saga<>.ReplyToOriginator 

我不请参阅与ReBus一起完成此操作的等效方式。有没有办法做到这一点,如果不是什么是一个好的模式(除了发起者投票)我可以使用它将实现相同的事情?一个例子就是试图创建一个客户,客户想要知道它何时创建,然后尝试更改其地址。

下面是客户方案的一个简单的例子我赶紧把在一起:

public class CreateCustomerSaga : Saga<CreateCustomerData>, 
    IAmInitiatedBy<CreateCustomerCommand>, 
    IHandleMessages<CustomerUniqunessCheckResult> 
{ 
    private readonly IBus _bus; 
    private readonly ICustomerResourceAccess _customerResourceAccess; 

    public CreateCustomerSaga(IBus bus, ICustomerResourceAccess customerResourceAccess) 
    { 
     _bus = bus; 
     _customerResourceAccess = customerResourceAccess; 
    } 

    public override void ConfigureHowToFindSaga() 
    { 
     Incoming<CustomerUniqunessCheckResult>(x => x.IsCustomerUnique).CorrelatesWith(y => y.CustomerId); 
    } 

    public void Handle(CreateCustomerCommand message) 
    { 
     Data.CustomerId = message.CustomerId; 
     Data.CustomerName = message.CustomerName; 

     _bus.Send(new CheckCustomerUniquenessCommand(message.CustomerId)); 
    } 

    public void Handle(CustomerUniqunessCheckResult message) 
    { 
     if (message.IsCustomerUnique) 
     { 
      _customerResourceAccess.CreateCustomer(Data.CustomerId, Data.CustomerName); 

      // This is what seems to be missing from ReBus to reply to the original sender 
      _bus.?(new CustomerCreatedEvent(Data.CustomerId)); 
     } 
     else 
     { 
      // This is what seems to be missing from ReBus to reply to the original sender 
      _bus.?(new CustomerAlreadExistsEvent(Data.CustomerId)); 
     } 
    } 
} 

public class CustomerCreatedEvent 
{ 
    public Guid CustomerId { get; set; } 

    public CustomerCreatedEvent(Guid customerId) 
    { 
     CustomerId = customerId; 
    } 
} 

public class CustomerAlreadExistsEvent 
{ 
    public Guid CustomerId { get; set; } 

    public CustomerAlreadExistsEvent(Guid customerId) 
    { 
     CustomerId = customerId; 
    } 
} 

public class CustomerUniqunessCheckResult 
{ 
    public bool IsCustomerUnique { get; set; } 
} 

public class CheckCustomerUniquenessCommand 
{ 
    public CheckCustomerUniquenessCommand(Guid customerId) 
    { } 
} 

public interface ICustomerResourceAccess 
{ 
    void CreateCustomer(Guid customerId, string customerName); 
} 

public class CreateCustomerCommand 
{ 
    public Guid CustomerId { get; set; } 

    public string CustomerName { get; set; } 
} 

public class CreateCustomerData : ISagaData 
{ 
    public CreateCustomerData() 
    { 
     Id = Guid.NewGuid(); 
    } 

    public Guid CustomerId { get; set; } 

    public string CustomerName { get; set; } 

    public Guid Id { get; set; } 

    public int Revision { get; set; } 
} 
+0

你有任何其他代码?你能简单介绍一下你所描述的技术吗?参与过去18年的编程,我不知道你在说什么。如果它是新的东西,如果可以将它与现有的技术联系起来,那就很好。 – Neolisk 2014-09-05 20:48:25

+1

我添加了一个示例,对于技术请参阅标签(ReBus,C#) – 2014-09-05 21:04:02

回答

3

没有呢,可惜没有回复鼻祖卤面传奇功能的时刻。您可以轻松地做到这一点,虽然,通过存储发送者的端点这样当创建您的传奇(在消息的所有Handle方法,可以发起传奇):

if (IsNew) { 
    Data.Originator = MessageContext.GetCurrent().ReturnAddress; 
} 

,然后当你要回复回发起者:

bus.Advanced.Routing.Send(Data.Originator, new HelloThereMyFriend()); 

我常想约增加这虽然画谜,无论是作为一个额外的字段上ISagaData,或作为一个额外的接口ISagaDataWithOriginator,你可以选择应用到你的传奇故事的数据,但我从来没有我自己有需要(足够)。

+0

谢谢你,我非常感谢你回答这个问题。 – 2014-09-08 13:33:57

1

如果每个发件人是一个单独的(虚拟)机,就像在我的实现,你可以通过使用他们的机器唯一的ID或MAC地址应答队列名称,像这样得到保证的回复鼻祖:

Bus = Configure.With(adapter) 
       .Transport(t => t.UseSqlServer(DbConfiguration.DatabaseConnectionString, 
               sInstanceId, sInstanceId + ".Error") 
       .EnsureTableIsCreated()) 
       ... 

如果每个发起者都有一个唯一的队列ID,则消费者可以简单地使用Bus.Reply来回复发起者。

可以使用System.Management来确定唯一的机器ID:

string uuid = string.Empty; 

ManagementClass mc = new System.Management.ManagementClass("Win32_ComputerSystemProduct"); 
if (mc != null) 
{ 
    ManagementObjectCollection moc = mc.GetInstances(); 
    if (moc != null) 
    { 
    foreach (ManagementObject mo in moc) 
    { 
     PropertyData pd = mo.Properties["UUID"]; 
     if (pd != null) 
     { 
     uuid = (string)pd.Value; 
     break; 
     } 
    } 
    } 
} 

或使用机器的MAC地址(我们的后备代码):

if (string.IsNullOrEmpty(uuid)) 
{ 
    uuid = NetworkInterface.GetAllNetworkInterfaces() 
    .Where(ni => ni.OperationalStatus == OperationalStatus.Up) 
    .FirstOrDefault() 
    .GetPhysicalAddress().ToString(); 
} 
相关问题