私は本当にいくつかの言葉で、私がより詳細に必要なものを記述することができるタイトルを考えることができませんでした。 最終的には、メッセージをAzure Service Bus
に送信するためのカスタム実装を使用しています。この実装はNuGet
パッケージにラップされています。QAの自動化に必要なメッセージをデータベースに保存するロジックを追加しようとしています。ここで難しいのは、NuGet
パッケージを変更せずに、すべての追加ロジックを "ラップ"したいということです。 パッケージ自体にはsealed
クラスとinternal
インターフェイスがたくさんありますが、私は必要なチェーンを抽出することができたと思います。身分証明書IDisposable
public interface IMessageBus : IDisposable
{
bool Send(IMessage command);
bool Send(IMessage command, string trackingId);
Task<bool> SendAsync(IMessage command);
Task<bool> SendAsync(IMessage command, string trackingId);
bool Publish(IMessage eventObj);
bool Publish(IMessage eventObj, string trackingId);
Task<bool> PublishAsync(IMessage eventObj);
Task<bool> PublishAsync(IMessage eventObj, string trackingId);
}
それがパッケージの一部ですが、いくつかpublic
インターフェースの一つである: まず私は、サービスバスにメッセージをパブリッシュするすべてのクラスから使用され、このインタフェースを持っています。それから私は、このインタフェースを実装する抽象クラスを持っている:
public abstract class MessageBusBase : IMessageBus, IDisposable
{
~MessageBusBase()
{
this.Dispose(false);
}
#region Interface
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize((object)this);
}
protected abstract bool SendMessage(IMessage payload, string trackingId);
protected abstract Task<bool> SendMessageAsync(IMessage payload, string trackingId);
protected abstract void Dispose(bool disposing);
}
ここからは私が実装の背後にある考え方を失い始めます。 IMessageBus
は既にIDisposable
を実装しているので、なぜ抽象クラスで再度実装する必要がありますか? Resharper
もこれを不要とマークしていますが、毎回Resharper
を信用しないことを学んだことがあります。誰かが抽象クラスで、なぜデストラクタの目的であるものを私に説明できる場合、私は本当に感謝この絵を持っ
public sealed class AzureMessageBus : MessageBusBase
{
private bool isDisposed;
#region MessageBusBase
protected override void Dispose(bool disposing)
{
if (!disposing)
return;
this.isDisposed = true;
foreach (IDisposable disposable in (IEnumerable<ISender>)this.senders.Values)
disposable.Dispose();
}
}
:
だから最後に私は抽象MessageBusBase
を継承sealed
クラスを持っていますそれが必要です。私は、デストラクタをいつ使うべきか、なぜそれを使うべきかについて読んでいるところですが、私が達する結論は、実際にはそれを必要としない可能性が最も高いということです。しかし、AzureMessageBus
ではAzure
への実際の呼び出しであり、メソッドで使用しているIMessage
インターフェイスもGoogle.ProtocolBuffers
です。これは答えかもしれませんが、今私はちょうど推測しています。これは私の質問の最初の部分です。
2番目の部分は私の追加ロジックを追加しています。私がやったこと、新しいクラス作成することによって:私は、元の実装を呼んでいる私の新しいクラスから
return (IMessageBus) new AzureMessageBus(..)
だから、基本的には、すべてです:this.messageFactory.CreateMessageBus();
はそうのようなAzureMessageBus
のインスタンスを返します
public class AzureMessageBusWithLogging : IMessageBus
{
private IMessageBus messageBus;
private IMessagingFactory messageFactory;
public AzureMessageBusWithLogging(IMessagingFactory msgFactory)
{
this.messageFactory = msgFactory;
if (messageFactory != null)
{
this.messageBus = this.messageFactory.CreateMessageBus();
}
}
public Task<bool> SendAsync(IMessage command, string trackingId)
{
//Place for my additional logic
return ((AzureMessageBus)messageBus).SendAsync(command, trackingId);
}
public void Dispose()
{
throw new NotImplementedException();
}
#region IMessageBus
}
を私は私の新しいクラスAzureMessageBusWithLogging
でIMessageBus
を実装する必要があるためAzureMessageBus
からの方法は、私は追加することを強制しています:
public void Dispose()
{
throw new NotImplementedException();
}
しかし、本当に何かをする必要がある場合、私は実際に何を入れるかわからない。また、私が実際にGC
の実装を必要としている理由(私の視点から見ると複雑なもの)と、新しいクラスの処分が既存のAzureMessageBus
に影響を与える可能性がある理由について、説明していただきたいと思います。私の新しいクラス。
'MessageBusBase'は、継承されたクラスにDisposeロジックを実装させる抽象的な' Dispose'メソッドを定義しています。実装に何も配置しない場合は、空のままにしてください。なぜあなたは例外をスローしますか(特に、このコードはファイナライザによって実行されると仮定します)。 –
@YeldarKurmangaliyev私はこのデザインでちょっと混乱しています。これは主に新しいものなので、今はあまりにも多くの時間を費やして「GC」を考えることはありません。だからこそ私はこの質問をしていますが、このデザインが何を目指しているのか(もしあれば)、そしてそれをこのように実装することで達成するものが何であるかはわかりません。だから、なぜ例外があるのか知りたい。そして、Disposeの答えに感謝します。私はまたそれを空のままにすることに傾いている。 – Leron