我真的無法想象一個標題,可以用幾個詞,描述我需要更多的細節。 最終的想法是我使用自定義實現來發送消息到Azure Service Bus
。這個實現被封裝在一個NuGet
包中,我試圖添加一些額外的邏輯,將消息保存到QA自動化目的所需的數據庫中。這裏棘手的部分是,我希望NuGet
包保持不變,所有額外的邏輯要「包裹」它。 所以包本身有很多sealed
類和internal
接口,但我想我已經設法提取我需要的鏈。 首先我有這個接口是從所有的類用於發佈消息到服務總線:Impementing 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
。
所以在最後我有sealed
類繼承抽象MessageBusBase
:
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();
}
}
有了這個圖片我真的很感激,如果有人可以給我解釋一下什麼是析構函數的抽象類,爲什麼目的我們需要。我花了一些時間閱讀關於什麼時候和爲什麼應該使用析構函數,以及我已經達到的結論是,實際上我們很可能不需要它。然而在AzureMessageBus
是Azure
的實際調用,我們在SendMessageAsync
方法中使用的IMessage
接口的實際調用是從Google.ProtocolBuffers
開始,也許這可能是答案,但現在我只是猜測。所以這是我的問題的第一部分。
第二部分是添加我的附加邏輯。我這樣做,通過創建一個新的類:
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
}
凡this.messageFactory.CreateMessageBus();
返回像這樣的AzureMessageBus
一個實例:
return (IMessageBus) new AzureMessageBus(..)
所以基本上這一切,從我的新類我打電話的原來的實現從AzureMessageBus
的方法,但因爲我需要在我的新類AzureMessageBusWithLogging
實施IMessageBus
我不得不補充:
public void Dispose()
{
throw new NotImplementedException();
}
但是我真的不知道該在裏面放什麼,如果我真的需要做點什麼。同時我也會很感激解釋爲什麼我們需要這個(從我的觀點來看很複雜)實現GC
以及如何以任何方式在我的新類中處置可能會影響現有的AzureMessageBus
,因爲我使用它的實例我的新班級。
'MessageBusBase'只是定義了一個抽象的Dispose方法,讓繼承類實現Dispose邏輯。如果在你的實現中沒有任何東西需要處理,那就把它留空。爲什麼拋出一個異常(特別是假設這個代碼將由finalizer運行)。 –
@YeldarKurmangaliyev我對這個設計有些困惑,主要是因爲它是新東西,直到現在我從不花太多時間思考'GC'。這就是爲什麼我問這個問題,不確定這個設計的目標是什麼(如果有的話)以及我們通過這種方式實現的目標。所以我也想知道爲什麼是例外。並感謝'Dispose'答案。我也傾向於將它留空。 – Leron