rebus-org / Rebus.AzureServiceBus

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

Create an extensibility point to name topics #11

Closed heberop closed 6 years ago

heberop commented 6 years ago

Creating an extensibility point to name topics is useful if you want to use another name convention, changing the default topic name based on type to bounded context.

For example, I would like to change the topic name from this: image

to this: image

I think we can create an extension method in AzureServiceBusTransportSettings to define the convention to name topics, like this:

internal Func<string, string> TopicNamingConvention { get; set; }
    = topic => topic.ToValidAzureServiceBusEntityName();

public AzureServiceBusTransportSettings EnableTopicNamingConvention(Func<string, string> convention)
{
    TopicNamingConvention = convention;

    return this;
}

Then, when we are configuring the endpoint:

services.AddRebus(configure => configure
                    .Logging(l => l.ColoredConsole())
                    .Transport(t => 
                        t.UseAzureServiceBus(connectionString, endpoint)
                            .EnablePrefetching(100)
                            .EnableTopicNamingConvention(topic => topic.MyConvention()))

Another way is to create an interface like INamingConvention and implementing that.

mookid8000 commented 6 years ago

I can definitely see how this would be useful, but I am not sure the Azure Service Bus transport would be the best place to add this extensibility point.

I am thinking that it might be a nice feature in general to be able to affect how Rebus maps types to topics. You can see how subscribe is implemented here: https://github.com/rebus-org/Rebus/blob/master/Rebus/Bus/RebusBus.cs#L198 - as you can see, it simply calls the GetSimpleAssemblyQualifiedName extension.

My initial idea would be extend the IRouter service with the ability to perform this mapping, and thus with the ability to be overridden...

What's your thoughts about this?

heberop commented 6 years ago

I agree with you that the IRouter interface is the natural place to put this functionality.

Do you have a suggestion of name for this method on IRouter interface? Or can I use TopicNameConvention?

heberop commented 6 years ago

I was reading the code and I think we can't modify IRouter because we can broke some custom implementation of IRouter.

So I thought if is better to create another interface like ITopicNameConvention and inject that in RebusBus. The default implementation will use GetSimpleAssemblyQualifiedName extension method and a custom name convention can be configured like this:

    .Routing(configurer =>
    {
        routes.ForEach(route => configurer
              .OtherService<ITopicNameConvention>(new MyCustomNameConvention()) 
              .TypeBased() /* maps */
    })

Or, using an extension method to avoid .OtherService().

Do you agree?

PS: I think we need to move these thread to Rebus repo ;)

mookid8000 commented 6 years ago

I was reading the code and I think we can't modify IRouter because we can broke some custom implementation of IRouter.

You are absolutely right about that 🙂 also, when thinking some more about it it's not really "routing", it's more about what happens right before routing, if you know what I mean?

PS: I think we need to move these thread to Rebus repo ;)

BAM! 👉 👉 👉 https://github.com/rebus-org/Rebus/issues/692