MassTransit and Interface Contracts

 MassTransit interface-style messages

Did you know that in MassTransit you can use interfaces for your message
contracts rather than classes? If not, you can and here is how.

Let’s take the following example:

public class RegisterSalesOrder
{
    public string OrderNumber { get; set; }
}

public class Program
{
    public static void Main())
    {
        var bus = BuildNewBus();
        bus.Publish(new RegisterSalesOrder { OrderNumber = "abc" });
    }
}

Nothing too surprising here I hope. We get our bus instance and then publish our
message. Later someone will consume it. Like so:

public class Program
{
    public static void Main()
    {
        var bus = ServiceBusFactory.New(sbc =>
        {
            //ignoring a bunch of setup
            sbc.Subscribe(subs =>
            {
                subs.Handler<RegisterSalesOrder>(msg =>
                {
                    //do stuff
                });
            })
        });
    }
}

more configuration options here

Why interfaces?

So this is great and all, but if our contract was that messages should be immutable
it would be nice to have that enforced by the compiler. But with classes that can
be tricky if we want to support being able to easily build the messages when
we need to as well. We could just use private setters, but now they are a pain
to build and would require constructor parameters which further makes
serialization a pain.

public class RegisterSalesOrder
{
    public string OrderNumber { get; private set; }
}

MassTransit support interface based contracts like this

public interface RegisterSalesOrder
{
    string OrderNumber { get; }
}

Now we have an immutable contract, and we can subscribe to this interface in
our subscription setup part of the bus. The trick is now in the publishing.
How do you create an interface and set its properties and publish it?

I simple create a class that implements the interface (outside of the contract dll). I usually make them in the publishing system as they are a private implementation detail of that system.

public class MyRegisterSalesOrder : RegisterSalesOrder
{
    public string OrderNumber { get; set; }
}

Now I can create an instance of the contract w/ ease and it can be made in whatever
way my publishing code needs it. It can be built using a ctor, a factory method,
through the container, whatever my app wants or needs. Then I can simply publish it

bus.Publish(new MyRegisterSalesOrder { OrderNumber = "bob" });

And subscribers to the interface will get the message as it conforms to the interface.

Boom.

About Dru Sellers

Sr. Software Engineer at Dovetail Software.
This entry was posted in MassTransit. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • drusellers

    In my VS setup its quite easy to see, because my interfaces are not the same color as my classes. I don’t think I missed his point, because I have this conversation w/ people all the time that are new to my code preferences. Thank you for pointing out that situation though. :)

  • Jarle Friestad

    I think you missed his point. From your example in the other post.

    public class RegisterBigCommerceSalesOrderCommand : RegisterSalesOrder, RegisterBigCommerceSalesOrder {…}

    Lets pretend you didn’t write that code and someone else did and you open the source code file for the first time. Would you know whether or not RegisterSalesOrder and RegisterBigCommerceSalesOrder are interfaces or classes (without having to hold the mouse cursor over the name or navigating to code file). Maybe RegisterSalesOrder is an abstract class and RegisterBigCommerceSalesOrder is an interface. Maybe both are interfaces.

  • eautcoins.com

    If there are specific examples of the better, combined with examples to better understand

  • Chris Patterson

    The suffix naming of types is a different part of the .NET framework guidelines, and is more to make implementations more concise to their implemented parts than a meaningless prefix designed in the era of black and white editors with no color differentiation between class and interface (or delegate for that matter).

    There are many I* interfaces in MassTransit, where it makes sense. Putting “I” in front of every command or event name just reads like shit and adds noise. Sort of like explicit internal and private modifiers where they are completely unnecessary.

  • drusellers

    i can answer your question w/o even looking at the code. No. Its .Net you can’t have double inheritance.

    I prefer to have an interface like ‘Encryptor’ and a class like ‘AESEncryptor’. I keep the exception on my exceptions because I find it helpful. I don’t find the ‘I’ prefix helpful. :)

  • drusellers

    Jimmy’s post on this is a solid post, his points are valid. None-the-less I choose to disagree, its my preference. I would be happy to blog about it in more detail if that is of interest. :)

  • Jarle Friestad

    http://lostechies.com/jimmybogard/2011/11/09/the-last-vestiges-of-hungarian-notation/

    “The train for picking different naming styles for interfaces and generic type parameter names left the station a long, long time ago. That ship has sailed. Picking a different naming convention that goes against years and years of prior art, established conventions and expectations is OK if you’re the only one who’s ever going to look at your code.

    If you do decide to ignore a decade of convention, you’re also deciding to irritate and confuse every .NET developer that reads your code when you’re done. Because every time someone else sees that interface without the “I”, the question will always come up on why that decision was made. Unless you’re just a complete sadist, just stick with the convention, please?”

    Another point is that the “I” indicates a contract meaning that you instantly know your dealing with a proxy/contract and not the implementation itself. You can also use the “I” as part of a better naming like “ICanConfigure”, “IContainConfiguration”, “IDeleteCustomer” etc. If you still decide drop the “I” from interfaces then you should do something like they do in the java world and add “Impl” on the concrete implementation instead off using the same name or prefixing it with “My….”.

    “IService, Service = lame”

    BTW I dont like when developer creates “services” and “managers” e.g “CustomerService” / “CustomerManager”. A service is just bundle of all the actions to be done with customer breaking the SRP of the code. Suddenly you have classes with over a 1000 lines off code. I rather create own classes for each type of actions “CustomerDeleter”, “CustomerAddressUpdater”, “CustomerRegistration”

  • Fabian Wetzel

    Well you are making a case for good naming. “Just stripping the I off” may really not be the best way to name implementations, but I think, I would go for IService and FileService or
    IConfigurationProvider and FileConfigurationProvider.

    I am just curious, do you stop calling your exception *Exception as well?

    and out of context from the next blog post by dru:

    public class RegisterBigCommerceSalesOrderCommand : RegisterSalesOrder, RegisterBigCommerceSalesOrder {…}

    Quick! is this double inheritance? ;-)

  • drusellers

    and now, i see the gist. sheesh.

  • drusellers

    I am going to assume you mean the private setters. If so, thank you. :)

  • João P. Bragança

    https://gist.github.com/thefringeninja/8230550

    Works with DataContract, Newtonsoft.Json, and protobuf serializers

  • drusellers

    How do you mean?

  • João P. Bragança

    DataContract and DataMember with the Order property set will fix your serialization problems with most serializers.

  • drusellers

    That’s pretty nifty

  • Chris Patterson

    Because “I” don’t think the hungarian notation adds any value, and it makes it feel like a header file. It also makes implementations stupid and not descriptive.

    IService, Service = lame

    ConfigurationProvider, FileConfigurationProvider – makes sense, encourages proper naming instead of just stripping the I off the front.

  • Chris Patterson

    You can pass an anonymous object with the same property names to publish and it will map them to the matching properties. Might even do some light type conversion as well, I can’t remember right now.

  • http://codebetter.com Brendan Tompkins

    Ahhh.. right… Hrm.. Dunno.

  • drusellers

    what if public interface IMyMessage { string Property1 { get; } } ??

  • http://codebetter.com Brendan Tompkins

    Bus.Publish<IMyMessage>(m => { m.Property1 = “My Value”; });

  • drusellers

    That would work too, but how would you set the properties?

  • drusellers
  • http://codebetter.com Brendan Tompkins

    Dru, In NService Bus, you can use the bus.CreateInstance<T> method to create an object without a class definition.. I’m curious about your thoughts on this approach rather than having to create the class in code.

  • Fabian Wetzel

    I like this idea as well! But why does your interface name not start with I*? like “IRegisterSalesOrder”?

  • craigsmitham

    I’m a fan of using interfaces for message contracts. Often I’ll have my MVC view models simply implement an interface, instead of worrying about mapping to some other command or message dto.