2014-09-05 45 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(); 
} 
相關問題