NServiceBus icon indicating copy to clipboard operation
NServiceBus copied to clipboard

Polymorphism support for AutoSubscribe DisableFor

Open danielmarbach opened this issue 3 years ago • 6 comments

Disabling auto subscribe for event types with polymorphism is currently not supported. So for the following event

public class MyEvent : IEventInterface {
}

the below disable will not work

var autoSubscribe = endpointConfiguration.AutoSubscribe();
autoSubscribe.DisableFor<IEventInterface>();

instead

var autoSubscribe = endpointConfiguration.AutoSubscribe();
autoSubscribe.DisableFor<MyEvent>();

has to be used. The reason is that the DisableFor API just adds the generic type to the type exclusions but the type might be scanned again and then transports might walk up the type hierarchy and include the interface type again into the subscription hierarchy even though the type was excluded.

            class MyMessageHandler : IHandleMessages<MyEvent>
            {
                public Task Handle(MyEvent message, IMessageHandlerContext context)
                {
                    return Task.FromResult(0);
                }
            }            
           class EventMessageHandler : IHandleMessages<IEventInterface>
            {
                public Task Handle(IEventInterface message, IMessageHandlerContext context)
                {
                    return Task.FromResult(0);
                }
            }

Currently, there is no way to disable autosubscribing for types in the middle of the hierarchy

danielmarbach avatar Mar 10 '21 07:03 danielmarbach

I think it would be a great feature. Sometimes interfaces are not used for messaging but rather for enforcing message contracts across types. Excluding an inherited object would be useful both for AutoSubscribe and for Publish.

natilivni avatar Mar 10 '21 08:03 natilivni

When will this feature be ready. I am having a problem with the following. I have a command DebitCustomerAccount and DepositMoney that inherits from DebitCustomerAccount. The problem is that handler gets executed twice

ekjuanrejon avatar Jun 07 '21 02:06 ekjuanrejon

@ekjuanrejon it would be best if you raised a support case. The inheritence is designed to be used with events that are published, not with commands. But in any case, handlers should not be called twice.

SzymonPobiega avatar Jun 07 '21 11:06 SzymonPobiega

@SzymonPobiega how do I open a support case? This is causing a big issue for me

ekjuanrejon avatar Jun 07 '21 15:06 ekjuanrejon

@SzymonPobiega

Looking at diagnostics... it has the following:

"CustomerService.Command.Contract.Accounts.DepositCustomerMoney": [
    "CustomerService.Command.ApplicationService.Accounts.DebitAccountHandler",
    "CustomerService.Command.ApplicationService.Accounts.DepositMoneyHandler"
  ],

I only want DepositMoney to be handled by DepositMoneyHandler and not by DebitAccountHandler

ekjuanrejon avatar Jun 07 '21 16:06 ekjuanrejon

The best channel for support is e-mail.

Regarding your problem, you need to change the message hierarchy to remove the inheritence. NServiceBus is designed in such a way that is executes all handlers that can handle a given type so a handler that is defined to handle a superclass also handles all derived classes, e.g. if you have:

MyMessage : IMessage and MyDerivedMessage : MyMessage

MyMessageHandler : IHandleMessages<MyMessage> is going to handle both MyMessage and MyDerivedMessage while MyDerivedMessageHandler : IHandleMessages<MyDerivedMessage> is going to handle only MyDerivedMessage.

SzymonPobiega avatar Jun 08 '21 07:06 SzymonPobiega