Search code examples
c#inheritanceabstract-class

Inheriting from abstract class in old Azure library (Microsoft.ServiceBus.Messaging namespace). No suitable method found to override


There is QueueClient abstract class in Microsoft.ServiceBus.Messaging namespace. I want to create a child class name MyQueueClient. I override all the methods that I can see in the QueueClient class, but I still get compile error:

Error CS0534 'MyQueueClient' does not implement inherited abstract member 'QueueClient.OnBeginCreateBrowser(TimeSpan, AsyncCallback, object)' Core

When I use VS intellisense suggestion to generate that method, then it gives me another compilation error:

'MyQueueClient.OnBeginCreateBrowser(TimeSpan, AsyncCallBack, object)', no suitable method found to override.

Here is QueueClient class (sorry for long code, but you can see all the abstract methods are coming at the end)

//
// Summary:
//     Represents the queue client object.
public abstract class QueueClient : MessagingEntityClient, IMessageSessionEntity, IMessageClientEntity, IMessageSender, IMessageReceiver, IMessageBrowser
{

    public MessagingFactory MessagingFactory { get; }

    public ReceiveMode Mode { get; }

    public int PrefetchCount { get; set; }

    public static QueueClient Create(string path, ReceiveMode mode);

    public static QueueClient Create(string path);

    public static QueueClient Create(Uri endpointAddress, string path, AuthenticationContext authContext, ClientAssertionCertificate clientAssertionCertificate, ReceiveMode mode = ReceiveMode.PeekLock, TimeSpan? operationTimeout = null, TransportType transportType = TransportType.NetMessaging);

    public static QueueClient Create(Uri endpointAddress, string path, AuthenticationContext authContext, string clientId, UserPasswordCredential userPasswordCredential, ReceiveMode mode = ReceiveMode.PeekLock, TimeSpan? operationTimeout = null, TransportType transportType = TransportType.NetMessaging);

    public static QueueClient Create(Uri endpointAddress, string path, AuthenticationContext authContext, string clientId, Uri redirectUri, IPlatformParameters platformParameters, UserIdentifier userIdentifier = null, ReceiveMode mode = ReceiveMode.PeekLock, TimeSpan? operationTimeout = null, TransportType transportType = TransportType.NetMessaging);

    public static QueueClient Create(Uri endpointAddress, string path, AuthenticationContext authContext, ClientCredential clientCredential, ReceiveMode mode = ReceiveMode.PeekLock, TimeSpan? operationTimeout = null, TransportType transportType = TransportType.NetMessaging);

    public static QueueClient CreateFromConnectionString(string connectionString, string path);

    public static QueueClient CreateFromConnectionString(string connectionString);

    public static QueueClient CreateFromConnectionString(string connectionString, string path, ReceiveMode mode);

    public static QueueClient CreateFromConnectionString(string connectionString, ReceiveMode mode);

    public static QueueClient CreateWithManagedServiceIdentity(Uri endpointAddress, string path, ReceiveMode mode = ReceiveMode.PeekLock, TimeSpan? operationTimeout = null, TransportType transportType = TransportType.NetMessaging);

    public void Abandon(Guid lockToken, IDictionary<string, object> propertiesToModify);

    public void Abandon(Guid lockToken);

    public Task AbandonAsync(Guid lockToken);

    public Task AbandonAsync(Guid lockToken, IDictionary<string, object> propertiesToModify);

    public MessageSession AcceptMessageSession(TimeSpan serverWaitTime);

    public MessageSession AcceptMessageSession(bool isExclusiveMode, TimeSpan serverWaitTime);

    public MessageSession AcceptMessageSession(bool isExclusiveMode);

    public MessageSession AcceptMessageSession(string sessionId, Guid lockToken, TimeSpan serverWaitTime);

    public MessageSession AcceptMessageSession(string sessionId, bool isExclusiveMode, TimeSpan serverWaitTime);

    public MessageSession AcceptMessageSession(string sessionId, Guid lockToken);

    public MessageSession AcceptMessageSession(string sessionId, bool isExclusiveMode);

    public MessageSession AcceptMessageSession(string sessionId);

    public MessageSession AcceptMessageSession(string sessionId, TimeSpan serverWaitTime);

    public MessageSession AcceptMessageSession();

    public Task<MessageSession> AcceptMessageSessionAsync(string sessionId, bool isExclusiveMode);

    public Task<MessageSession> AcceptMessageSessionAsync(string sessionId, Guid lockToken);

    public Task<MessageSession> AcceptMessageSessionAsync(string sessionId);

    public Task<MessageSession> AcceptMessageSessionAsync(string sessionId, bool isExclusiveMode, TimeSpan serverWaitTime);

    public Task<MessageSession> AcceptMessageSessionAsync(string sessionId, Guid lockToken, TimeSpan serverWaitTime);

    public Task<MessageSession> AcceptMessageSessionAsync(TimeSpan serverWaitTime);

    public Task<MessageSession> AcceptMessageSessionAsync(string sessionId, TimeSpan serverWaitTime);

    public Task<MessageSession> AcceptMessageSessionAsync(bool isExclusiveMode);

    public Task<MessageSession> AcceptMessageSessionAsync(bool isExclusiveMode, TimeSpan serverWaitTime);

    public Task CancelScheduledMessageAsync(long sequenceNumber);

    public void Complete(Guid lockToken);

    public void CompleteBatch(IEnumerable<Guid> lockTokens);

    public Task CompleteBatchAsync(IEnumerable<Guid> lockTokens);

    public void DeadLetter(Guid lockToken);

    public void DeadLetter(Guid lockToken, string deadLetterReason, string deadLetterErrorDescription);

    public void DeadLetter(Guid lockToken, IDictionary<string, object> propertiesToModify);

    public Task DeadLetterAsync(Guid lockToken, IDictionary<string, object> propertiesToModify);

    public Task DeadLetterAsync(Guid lockToken);

    public Task DeadLetterAsync(Guid lockToken, string deadLetterReason, string deadLetterErrorDescription);

    public void Defer(Guid lockToken);

    public void Defer(Guid lockToken, IDictionary<string, object> propertiesToModify);

    public Task DeferAsync(Guid lockToken);

    public Task DeferAsync(Guid lockToken, IDictionary<string, object> propertiesToModify);

    public IEnumerable<MessageSession> GetMessageSessions();

    public IEnumerable<MessageSession> GetMessageSessions(DateTime lastUpdatedTime);

    public Task<IEnumerable<MessageSession>> GetMessageSessionsAsync(DateTime lastUpdatedTime);

    public Task<IEnumerable<MessageSession>> GetMessageSessionsAsync();

    public void OnMessage(Action<BrokeredMessage> callback);

    public void OnMessage(Action<BrokeredMessage> callback, OnMessageOptions onMessageOptions);

    public void OnMessageAsync(Func<BrokeredMessage, Task> callback, OnMessageOptions onMessageOptions);

    public void OnMessageAsync(Func<BrokeredMessage, Task> callback);

    public BrokeredMessage Peek();

    public BrokeredMessage Peek(long fromSequenceNumber);

    public Task<BrokeredMessage> PeekAsync();

    public Task<BrokeredMessage> PeekAsync(long fromSequenceNumber);

    public IEnumerable<BrokeredMessage> PeekBatch(int messageCount);

    public IEnumerable<BrokeredMessage> PeekBatch(long fromSequenceNumber, int messageCount);

    public Task<IEnumerable<BrokeredMessage>> PeekBatchAsync(long fromSequenceNumber, int messageCount);

    public Task<IEnumerable<BrokeredMessage>> PeekBatchAsync(int messageCount);

    public BrokeredMessage Receive(long sequenceNumber);

    public BrokeredMessage Receive(TimeSpan serverWaitTime);

    public BrokeredMessage Receive();

    public Task<BrokeredMessage> ReceiveAsync(TimeSpan serverWaitTime);

    public Task<BrokeredMessage> ReceiveAsync();

    public Task<BrokeredMessage> ReceiveAsync(long sequenceNumber);

    public IEnumerable<BrokeredMessage> ReceiveBatch(IEnumerable<long> sequenceNumbers);

    public IEnumerable<BrokeredMessage> ReceiveBatch(int messageCount, TimeSpan serverWaitTime);

    public IEnumerable<BrokeredMessage> ReceiveBatch(int messageCount);

    public Task<IEnumerable<BrokeredMessage>> ReceiveBatchAsync(int messageCount, TimeSpan serverWaitTime);

    public Task<IEnumerable<BrokeredMessage>> ReceiveBatchAsync(int messageCount);

    public Task<IEnumerable<BrokeredMessage>> ReceiveBatchAsync(IEnumerable<long> sequenceNumbers);

    public void RegisterSessionHandler(Type handlerType, SessionHandlerOptions options);

    public void RegisterSessionHandler(Type handlerType);

    public Task RegisterSessionHandlerAsync(Type handlerType, SessionHandlerOptions options);

    public Task RegisterSessionHandlerAsync(Type handlerType);

    public void RegisterSessionHandlerFactory(IMessageSessionAsyncHandlerFactory factory, SessionHandlerOptions options);

    public void RegisterSessionHandlerFactory(IMessageSessionHandlerFactory factory, SessionHandlerOptions options);

    public Task RegisterSessionHandlerFactoryAsync(IMessageSessionHandlerFactory factory, SessionHandlerOptions options);

    public Task RegisterSessionHandlerFactoryAsync(IMessageSessionAsyncHandlerFactory factory, SessionHandlerOptions options);

    public DateTime RenewMessageLock(Guid lockToken);

    public Task<DateTime> RenewMessageLockAsync(Guid lockToken);

    public Task<long> ScheduleMessageAsync(BrokeredMessage message, DateTimeOffset scheduleEnqueueTimeUtc);

    public void Send(BrokeredMessage message);

    public Task SendAsync(BrokeredMessage message);

    public void SendBatch(IEnumerable<BrokeredMessage> messages);

    public Task SendBatchAsync(IEnumerable<BrokeredMessage> messages);

    protected abstract IAsyncResult OnBeginAcceptMessageSession(string sessionId, ReceiveMode receiveMode, int prefetchCount, bool isExclusiveMode, Guid? lockToken, TimeSpan serverWaitTime, TimeSpan timeout, AsyncCallback callback, object state);

    protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state);

    protected abstract IAsyncResult OnBeginCreateReceiver(ReceiveMode receiveMode, TimeSpan timeout, AsyncCallback callback, object state);

    protected abstract IAsyncResult OnBeginCreateSender(TimeSpan timeout, AsyncCallback callback, object state);

    protected abstract MessageSession OnEndAcceptMessageSession(IAsyncResult result);

    protected override void OnEndClose(IAsyncResult result);

    protected abstract MessageReceiver OnEndCreateReceiver(IAsyncResult result);

    protected abstract MessageSender OnEndCreateSender(IAsyncResult result);

    protected abstract IEnumerable<MessageSession> OnEndGetMessageSessions(IAsyncResult result);
}

And here is my child class:

public class MyQueueClient : QueueClient
{
    protected override IAsyncResult OnBeginAcceptMessageSession(string sessionId, ReceiveMode receiveMode, int prefetchCount, bool isExclusiveMode, Guid? lockToken, TimeSpan serverWaitTime, TimeSpan timeout, AsyncCallback callback, object state)
    {
        throw new NotImplementedException();
    }

    protected override IAsyncResult OnBeginCreateReceiver(ReceiveMode receiveMode, TimeSpan timeout, AsyncCallback callback, object state)
    {
        throw new NotImplementedException();
    }

    protected override IAsyncResult OnBeginCreateReceiver(string subQueueName, ReceiveMode receiveMode, TimeSpan timeout, AsyncCallback callback, object state)
    {
        throw new NotImplementedException();
    }

    protected override IAsyncResult OnBeginCreateSender(TimeSpan timeout, AsyncCallback callback, object state)
    {
        throw new NotImplementedException();
    }

    protected override IAsyncResult OnBeginGetMessageSessions(DateTime lastUpdatedTime, AsyncCallback callback, object state)
    {
        throw new NotImplementedException();
    }

    protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
    {
        throw new NotImplementedException();
    }

    protected override MessageSession OnEndAcceptMessageSession(IAsyncResult result)
    {
        throw new NotImplementedException();
    }

    protected override MessageReceiver OnEndCreateReceiver(IAsyncResult result)
    {
        throw new NotImplementedException();
    }

    protected override MessageSender OnEndCreateSender(IAsyncResult result)
    {
        throw new NotImplementedException();
    }

    protected override IEnumerable<MessageSession> OnEndGetMessageSessions(IAsyncResult result)
    {
        throw new NotImplementedException();
    }

    protected override void OnEndOpen(IAsyncResult result)
    {
        throw new NotImplementedException();
    }
}

There are 9 abstract methods in QueueClient[from metadata] class, and I override all of them with no error. But then it asked to implement 'OnBeginCreateBrowser' method, which is not there.


Solution

  • The OnBeginCreateBrowser and OnEndCreateBrowser methods are internal - so basically, even though it's an abstract class, you can't derive from it yourself.

    While this may be frustrating, it can be a very useful design technique within libraries, where you want to provide a layer of abstraction for consumers, but without necessarily providing the ability for them to supply an implementation.