1

私は ReBus で Sagas に取り組んでおり、NServiceBus での私の経験から、Saga の元の作成者に返信して、次のような更新を提供することができます。

 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; }
}
4

2 に答える 2

3

いいえ、残念ながら、現時点で Rebus のサガにはオリジネーター機能への回答はありません。ただし、サガが次のように作成されたときに発信者のエンドポイントを保存することで、簡単に行うことができます (Handleサガを開始できるメッセージのすべてのメソッドで)。

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

そして、発信者に返信したい場合:

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

これを Rebus に追加することをよく考えましISagaDataISagaDataWithOriginator

于 2014-09-06T21:12:53.113 に答える
1

私の実装のように、各送信者が個別の (仮想) マシンである場合、次のように、応答キュー名にマシン固有の ID または MAC アドレスを使用することで、発信者への応答を保証できます。

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

各オリジネーターが一意のキュー ID を持っている場合、コンシューマーは Bus.Reply を使用するだけでオリジネーターに返信できます。

一意のマシン ID は、System.Management を使用して決定できます。

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();
}
于 2015-05-01T18:50:03.117 に答える