Messaging in .NET: MessageBus vs .NET events vs directly invoking a method

887 views
Skip to first unread message

Charles Strahan

unread,
Aug 1, 2011, 1:09:03 PM8/1/11
to software_cr...@googlegroups.com
Hello all,

I've found that there exist three common methods of messaging in .NET:
  1. Use a *MessageBus, which sits between the subscriber and publisher.
  2. Creating a .NET event and explicitly subscribing.
  3. Directly invoke some method on the "subscriber".
    • Note that I consider methods just another form of messaging passing, although I don't know if that's a common model.
*Where "MessageBus" might look like:

    public class MessageBus : IMessageBus
    {
        private readonly IWindsorContainer container;

        public MessageBus(IWindsorContainer container)
        {
            this.container = container;
        }

        public void Publish<TMessage>(TMessage message) where TMessage : class, IMessage
        {
            var eventHandlers = container.ResolveAll<IMessageHandler<TMessage>>();
            foreach (var eventHandler in eventHandlers)
            {
                eventHandler.Handle(message);
            }
        }
    }

What I'm curious about is how one more skilled than myself decides which option to take.  Of course, the choice is pretty obvious in some cases: I know of no one that would make the interface to their Repositories consist of sending commands via a MessageBus - one would directly invoke a method on their Repository reference.

My thoughts on each:
  1. Use a MessageBus, which sits between the subscriber and publisher.
    • Very loosely coupled - publishers never need to know how their message gets to the interested observers.
    • Convenient for dependency injection.
    • Anything with a reference to the MessageBus can publish. Good thing... or bad thing?
  2. Creating a .NET event and explicitly subscribing.
    • Subscribers have direct control over who they listen to.
    • Moderate coupling.
  3. Directly invoke some method on the "subscriber" (perhaps subscriber in this case is injected into publisher).
    • Typically suits a 1:1 relationship between the "subscriber" and "publisher".
    • Highly coupled - the subscribing instance must match in type.

If I had to come up with some general rules for deciding among the three:
  1. Use a MessageBus, which sits between the subscriber and publisher.
    • Use in the Domain layer, capturing the essence of (and modeling) the natural events of the business. (Perhaps weather updates, stock price fluctuations, whatever)
  2. Creating a .NET event and explicitly subscribing.
    • Use in supporting infrastructure. Theoretically, if you had to roll your own TcpClient you'd want to use an event to model the "connected" event.
  3. Directly invoke some method on the "subscriber" (perhaps subscriber in this case is injected into publisher).
    • Again, use in supporting infrastructure. You could always supply a callback for one-off subscriptions. If you wouldn't use any sort of callback mechanism for encoding some bytes (unless it's truly an async operation).

Any thoughts? I'm sure these observations are pretty elementary; however, I haven't seen anyone lay out any rigorous guidance on this aspect of design. Ultimately, one could construct any software out of exclusively any one of those patterns, although I doubt anyone would ever think that's a good idea.

So, how do you decide which option to go with?


-Charles 

ROBERT JOHNSON

unread,
Aug 2, 2011, 11:47:22 PM8/2/11
to software_cr...@googlegroups.com
Hi Charles,

I have been looking at this message for two days now and desperately want to reply to encourage my fellow .NET developers to participate in SC. But sadly, I am just not that experienced in messaging models. I have heard many good things about the EventAggregator pattern, CQRS and Reactive extensions in the .NET space. Have you had any exposure to them? Messaging in .NET seems to be the domain of Udi Dahan currently are you familiar with him?

Bobby

--
You received this message because you are subscribed to the Google Groups "software_craftsmanship" group.
To post to this group, send email to software_cr...@googlegroups.com.
To unsubscribe from this group, send email to software_craftsma...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/software_craftsmanship?hl=en.

Alastair Smith

unread,
Aug 3, 2011, 3:29:04 AM8/3/11
to software_cr...@googlegroups.com
I had the same reaction, really - I just don't know enough about messaging.  

I can say, however, that I've been playing around with the Reactive Extensions for a couple of weeks now, and although there's a large learning curve, they're pretty sweet to use: LINQ to Events is a pretty powerful concept.  Unfortunately the steep learning curve is hampered by the fact that the XML documentation on the library is non-existent, and it's changing so often that many of the web examples are out of date.  However, there are some really great videos on Channel 9 that are more up-to-date.  

Ian Cooper is your man on CQRS if you want to investigate that (he and Greg Young have blogged about it extensively on CodeBetter.com, and http://cqrsinfo.com/ is a good resource too).  Bobby's right that Udi Dahan is big on messaging in .NET.  

Alastair

--
Alastair Smith MEng DipABRSM
http://www.alastairsmith.me.uk/

Mark Nijhof

unread,
Aug 3, 2011, 3:40:18 AM8/3/11
to software_craftsmanship
If you are interested in looking at a CQRS example written in C# then
you
may want to look at mine:
https://github.com/MarkNijhof/Fohjin/tree/master/Fohjin.DDD.Example

I'd be happy to answer questions on it as well and I wrote several
posts
about the example as well which are linked from the readme. It is
however my
last bit of public C# code and about a year and a half old, so a bit
fuzzy
:P

Cheers,

-Mark


On Aug 3, 9:29 am, Alastair Smith <alast...@alastairsmith.me.uk>
wrote:
> I had the same reaction, really - I just don't know enough about messaging.
>
> I can say, however, that I've been playing around with the Reactive
> Extensions for a couple of weeks now, and although there's a large learning
> curve, they're pretty sweet to use: LINQ to Events is a pretty powerful
> concept.  Unfortunately the steep learning curve is hampered by the fact
> that the XML documentation on the library is non-existent, and it's changing
> so often that many of the web examples are out of date.  However, there are
> some really great videos <http://channel9.msdn.com/Tags/rx/> on Channel 9
> that are more up-to-date.
>
> Ian Cooper is your man on CQRS if you want to investigate that (he and Greg
> Young have blogged about it
> extensively<http://codebetter.com/globalsearch/?cx=005178204031477491434%3A2bg5jt...>on
> CodeBetter.com, andhttp://cqrsinfo.com/is a good resource too).  Bobby's right that Udi Dahan
> is big on messaging in .NET.
>
> Alastair
>
> --
> Alastair Smith MEng DipABRSMhttp://www.alastairsmith.me.uk/
>
> On 3 August 2011 04:47, ROBERT JOHNSON <bobby.john...@gmail.com> wrote:
>
>
>
>
>
>
>
> > Hi Charles,
>
> > I have been looking at this message for two days now and desperately want
> > to reply to encourage my fellow .NET developers to participate in SC. But
> > sadly, I am just not that experienced in messaging models. I have heard many
> > good things about the EventAggregator pattern, CQRS and Reactive extensions
> > in the .NET space. Have you had any exposure to them? Messaging in .NET
> > seems to be the domain of Udi Dahan currently are you familiar with him?
>
> > Bobby
>
> > On Aug 1, 2011, at 10:09 AM, Charles Strahan wrote:
>
> > Hello all,
>
> > I've found that there exist three common methods of messaging in .NET:
>
> >    1. Use a *MessageBus, which sits between the subscriber and publisher.
> >    2. Creating a .NET event and explicitly subscribing.
> >    3. Directly invoke some method on the "subscriber".
> >       - Note that I consider methods just another form of messaging
> >       passing, although I don't know if that's a common model.
>
> > **Where "MessageBus" might look like:*
> > *
> > *
> >      public class MessageBus : IMessageBus
> >      {
> >          private readonly IWindsorContainer container;
>
> >          public MessageBus(IWindsorContainer container)
> >          {
> >              this.container = container;
> >          }
>
> >          public void Publish<TMessage>(TMessage message) where TMessage :
> > class, IMessage
> >          {
> >              var eventHandlers = container.ResolveAll<IMessageHandler<
> > TMessage>>();
> >              foreach (var eventHandler in eventHandlers)
> >              {
> >                  eventHandler.Handle(message);
> >              }
> >          }
> >      }
>
> > What I'm curious about is how one more skilled than myself decides which
> > option to take.  Of course, the choice is pretty obvious in some cases: I
> > know of no one that would make the interface to their Repositories consist
> > of sending commands via a MessageBus - one would directly invoke a method on
> > their Repository reference.
>
> > My thoughts on each:
>
> >    1. Use a MessageBus, which sits between the subscriber and publisher.
> >       - Very loosely coupled - publishers never need to know how their
> >       message gets to the interested observers.
> >       - Convenient for dependency injection.
> >       - Anything with a reference to the MessageBus can publish. Good
> >       thing... or bad thing?
> >    2. Creating a .NET event and explicitly subscribing.
> >       - Subscribers have direct control over who they listen to.
> >       - Moderate coupling.
> >    3. Directly invoke some method on the "subscriber" (perhaps subscriber
> >    in this case is injected into publisher).
> >       - Typically suits a 1:1 relationship between the "subscriber" and
> >       "publisher".
> >       - Highly coupled - the subscribing instance must match in type.
>
> > If I had to come up with some general rules for deciding among the three:
>
> >    1. Use a MessageBus, which sits between the subscriber and publisher.
> >       - Use in the Domain layer, capturing the essence of (and modeling)
> >       the natural events of the business. (Perhaps weather updates, stock price
> >       fluctuations, whatever)
> >    2. Creating a .NET event and explicitly subscribing.
> >       - Use in supporting infrastructure. Theoretically, if you had to
> >       roll your own TcpClient you'd want to use an event to model the "connected"
> >       event.
> >    3. Directly invoke some method on the "subscriber" (perhaps subscriber
> >    in this case is injected into publisher).
> >       - Again, use in supporting infrastructure. You could always supply a
> >       callback for one-off subscriptions. If you *wouldn't* use *any* sort
> >       of callback mechanism for encoding some bytes (unless it's truly an async
> >       operation).
>
> > Any thoughts? I'm sure these observations are pretty elementary; however, I
> > haven't seen anyone lay out any rigorous guidance on this aspect of design.
> > Ultimately, one could construct any software out of *exclusively* any one
> > of those patterns, although I doubt anyone would ever think that's a good
> > idea.
>
> > So, how do *you* decide which option to go with?

David Starr

unread,
Aug 3, 2011, 10:17:39 AM8/3/11
to software_cr...@googlegroups.com
The code Mark is referencing is worth reading just to read elegant code. Very good.

David Starr
Scrum.orgImproving the Profession of Software Development
Blog: elegantcode.com | @elegantcoder

Simone Busoli

unread,
Aug 3, 2011, 7:05:16 PM8/3/11
to software_cr...@googlegroups.com
Hi Mark, I've had a chance to look at your code in addition to attending Greg's workshops and reading about Event Sourcing applied in the context of CQRS. Honestly I'm not interested much about the separation between the write and the read model as in CQRS, rather about using events for reconstituting object state as in Event Sourcing. It would be very interesting to hear your thoughts about its use in production, which I assume you did starting perhaps one year and a half ago :)
Specifically, I am not very comfortable in the overall shift from the classic programming model that event sourcing entails (ApplyEvent, Apply, ...), as it sounds quite hard to fallback on the classic model if something goes wrong for any reason - you take it all or none.

Thoughts?

Kalle Launiala

unread,
Aug 4, 2011, 10:17:31 AM8/4/11
to software_craftsmanship
Hi,

Regardless of which model you mean by "classic model", you can
logically achieve much of the "event sourcing" in following way:
- Recognize the logical commands/service operations to logically pure.
In case you have much of CRUD-alike operations with many parameters,
you might want to look at structured code generation to handle them.
- Serialize the command alike as in event sourcing/event storing, so
that you can play back it accordingly.
- Behave synchronously or asynchronously as scaling down would be
another choise to make, not bound to the first one.

In case your commands are logically "pure" and properly crafted (even
for CRUD style all-parameters-in-neutral-update fashion), you can even
change the business logic behind the software and apply "CQRS + ES"
with aggregate roots and denormalizers afterwards.

Simply put, in your serialized command stack you have all the factual
information that in any form is changing the system. It's like
database's transaction log, except that you can alter your software
behind it.

Or even have multiple different versions in parallel; simply feeding
the same command chain to all of them.

I hope I didn't misinterpret your need.

Kalle Launiala

Charles Strahan

unread,
Aug 4, 2011, 5:46:49 PM8/4/11
to software_cr...@googlegroups.com


If you are interested in looking at a CQRS example written in C# then
you
may want to look at mine:
https://github.com/MarkNijhof/Fohjin/tree/master/Fohjin.DDD.Example
I'd be happy to answer questions on it as well and I wrote several
posts
about the example as well which are linked from the readme. It is
however my
last bit of public C# code and about a year and a half old, so a bit
fuzzy
:P
Cheers,
-Mark

Sweet - I'll check that out. And thank you for offering to answer any questions - I just might take you up on that offer :).

-Charles

Charles Strahan

unread,
Aug 4, 2011, 6:08:32 PM8/4/11
to software_cr...@googlegroups.com

Simply put, in your serialized command stack you have all the factual
information that in any form is changing the system. It's like
database's transaction log, except that you can alter your software
behind it.

That's something that's held my interest for some time now. I've always found it a bit of a pain in the neck to handle data in a "historical context" (a classic example: keeping track of the price of order items at the point of sale).  Throughout my experience with data stores, I have yet to discover a database (or supporting framework) that treats both the "when did this change?" and the "why did it change?" as first class concepts. It just "feels" like there must be some room for unification there. Event sourcing looks like a step in the right direction, so I'll have to play around with it (and CQRS) sometime.


Is anyone (other than Greg Young) using CQRS + ES in a mission critical environment?  It seems like it's everyone's favorite thing to blog about these days, but I wonder how many devs have put their paycheck on the line to actually use it in a production system :).

-Charles

Kalle Launiala

unread,
Aug 5, 2011, 1:21:34 AM8/5/11
to software_craftsmanship
Hi,

I'll claim better, so you don't feel like you're going to put your
paycheck on it either ;-)

Theres a completely open methodology (my invention yes, but it's
completely open, standards based, fully open source), that allows you
creating both applications in parallel with minimal effort.

CQRS + ES and Rich domain model (with complete command storage for
replay) side-by-side.

So while the aggregate roots + denormalizers differ from rich domain
model validation, you will spot the difference the second that you can
solve your problem on the rich domain model, but cannot do it in CQRS
+ ES.



You can check the (ugly as well, but technically correct) videos for
simplification (I use the word trivialization, which I have heard has
huge negative impact, but I didn't know that at the time).

The full source code (that with Android toolchain installed, will
allow you to make full n-tier architecture CQRS+ES & Android client
app within minutes) is available here - Note, take the "Mobile Clients
Trivialized" package:

The database is self-created and automatically updated (although event
changes are not currently supported properly, but the source code is
all there for anyone to start using and fix properly). It's really
"F5" experience on getting your CQRS model running - if there are any
issues, don't hesitate to mail me directly or post the linked
newsgroup.

http://abstractiondev.wordpress.com/case-study-cqrs/

The rich domain model generators are not there yet, but its
straightforward to add and we're adding them as well to provide
alternative (for us and for everyone else).

Because in the end of the day, I'm also still suspicious if CQRS +
aggregate roots. I'm going to make the apps in parallel, because
there's a way to do it.


Kalle
Reply all
Reply to author
Forward
0 new messages