rebus-org / Rebus.AzureServiceBus

:bus: Azure Service Bus transport for Rebus
https://mookid.dk/category/rebus
Other
33 stars 20 forks source link

Topic and subscription naming standard #39

Closed sabbadino closed 3 years ago

sabbadino commented 4 years ago

Hi, is it possible to plug a custom naming standard in topic and subscription creation ? I'm a little bit uncomfortable to know that moving a message class around namespace and assembly will "silently" (as far as I've understood) create new topic and subscription and leave the previous ones hanging around in asb. Thank you , enrico

mookid8000 commented 4 years ago

It's certainly possible 😄

By default, Rebus will use the (rather long) assembly-qualified name of events to come up with topic names.

You can register your own implementation of ITopicNameConvention, if you want to affect how .NET types are mapped to names.

You could e.g. create an extension method that looks like this:

public static class ShortAndReadableTopicsRebusConfigurationExtensions
{
    public static void UseShortTopicNames(this OptionsConfigurer configurer)
    {
        configurer.Decorate<ITopicNameConvention>(c => new ShortTopicNamesConvention());
    }

    class ShortTopicNamesConvention : ITopicNameConvention
    {
        public string GetTopic(Type type) => type.Name;
    }
}

(in this case simply using the short class name as the topic), which would then make it possible to configure Rebus like this:

Configure.With(...)
    .(...)
    .Options(o => {
        o.UseShortTopicNames();
    })
    .Start();

You could of course come up with all kinds of schemes to match what you're trying to do. E.g. if you want more strict control with your topic names, your naming convention could consist of a dictionary mapping from types to their topics.

I hope you find it usable 😄

sabbadino commented 4 years ago

Great ! I'll give it a try. Thank you

kristofdegrave commented 3 years ago

@mookid8000 I'm using this approach, but I get the following exception when I'm registering my custom ITopicNameConvention:

System.InvalidOperationException: 'Attempted to register primary 
-> Rebus.Topic.ITopicNameConvention, but a primary registration already exists: primary 
-> Rebus.Topic.ITopicNameConvention'

In this case the registered ITopicNameConvention is DefaultAzureServiceBusTopicNameConvention.

mookid8000 commented 3 years ago

Ah, sorry! I've changed the code snippet above to Decorateing instead of Registering the convention... could you try that instead?

kristofdegrave commented 3 years ago

That works, thx for the quick answer @mookid8000

Boggot commented 3 years ago

@mookid8000 Sorry to bother you, but i am also using this approach for customising my topics due to company policy on naming convention in azure.

Im using the following code to customise my topic names:

class ShortTopicNamesConvention : ITopicNameConvention { public string GetTopic(Type type) => $"sbt-{type.Name}"; }

However when i try to subscribe to a message in my saga like so:

provider.UseRebus(async bus => await bus.Subscribe<FileParsingCompleted>());

I get the following exception:

The topic 'sbt-FileParsingCompleted' could not be mapped to a message type! When using the type-based router, only topics based on proper, accessible .NET types can be used!

Im sure its something silly im doing but any help would be greatly appreciated.

mookid8000 commented 3 years ago

This is weird – it should not be possible to get this exception when using Rebus' Azure Service Bus transport – it should only be possible when using the "distributed mode" of pub/sub, which means that a subscriber actually sends a SubscribeRequest to the publisher to subscribe to events from it – and it's not necessary to do that with Azure Service Bus.

Could you maybe tell me a little bit more about your configuration? (e.g. show your Configure.With(..) / services.AddRebus(..) code)

Boggot commented 3 years ago

Hi @mookid8000 and thanks for the quick response. I must apologise! When you mentioned about checking the configuration i realised my mistake. I was running my app locally where SQL is the transport mechanism. Its only when i release the app to Azure that i use Azure Service Bus.

Thanks again!