Thinking About Verbs

Architecture, Distributed Systems, General Coding, Improvement, Techniques

In my last post, I said you should model verbs, not nouns. I probably exaggerated a bit (I tend to do that) – you shouldn’t completely forget about the nouns. Your verbs wouldn’t have much to do without them. Instead, you should be focused on the verbs and the details of the interactions, not the details of the nouns and adjectives (those will take care of themselves).

Your users want to use your application to get work done. As a I said, gone are the days of simple data entry applications (well, not completely, but certainly anyone building new products isn’t working on solving data entry problems). They want to perform tasks using your application – ordering a book is a task, not a data entry activity. Dispensing a medication, verifying the number of 2x4s in stock, checking a book out of a library – tasks, all.

This is not a new concept. Microsoft published an article about Inductive User Interfaces back in February, 2001 (Inductive was their term for task-based). Tasks have been the focus of various writings about Domain Driven Design, CQRS, and Event Sourcing. Another similar approach is the DCI Architecture, which is a little more formal but also acknowledges the importance of the verbs (or interactions, as they are called).

Which of these approaches, architectures, or techniques you use isn’t overly important. What is important is that you consider the verbs, the events, and the interactions. My last post came from a meeting we had at my company talking about how best to handle data transfer objects. We came to the realization that it was better to have a different DTO for every context, even if they contained the same properties, because as time went on, each of these objects would have their own reasons to change.

This led to trying to determine how best to name these things. How do you differentiate between 6 different OrderDTO classes? The answer is, you don’t – the order isn’t the important part. You focus on what the consumer of the DTO is trying to achieve and use that for the name. This is of course a fairly contrived starting point for a discussion of verbs – I still am starting from nouns (orders are nouns). But it led to further discussion about the way we needed to think about things – in terms of the interactions. If we had started there, we would have had an easier time of things. Fortunately the system under discussion still has a ways to go and we have plenty of time to make use of the lesson.

Special thanks to Matt Otto, who reminded me of DCI Architecture, as well as linked me to this very amusing article that basically makes the same points, although much better.

Advertisement

Model the Verbs, Not the Nouns

Architecture, Distributed Systems, General Coding, Improvement, Techniques

For most of my career, the “best practice” has been to build applications from the data up. You model the database and then everything will be happy. Its just the way you do it. There is no other way.

So what’s the problem? You end up building applications around what data you need to display and what data you will update. So you show the user all of the data they might need, because you don’t know what they need. You ask for all sorts of data, because you might need it for some scenario. You build screens that they can use to enter any changes that might occur with this data, no matter why those changes are required.

The problem with this approach is there is no “why?”. Why are you showing the user this data? Why are they updating it? What is it that they are really trying to do? You end up with a lot of very obtuse code that is hard to follow, because its only concern is pushing data to the screen from the database, or vice versa. It flows through a lot of logic that you might need in case of various scenarios, but its impossible to know what rules apply to what scenarios, because there is nothing about your code to imply intent.

Back when I started in this field, I was building applications to allow users to put paper forms into databases. There really wasn’t much more logic than that. I was not alone in this – its what most applications did back in the early 90’s. We were trying to build the paperless office, after all.

We can do so much more now. In fact, our users expect it. In order to do so, though, we need to think about the behavior that is expected. What is the user trying to accomplish? Why? What is the intent?

If we examined the behavior, the verbs of the system, instead of just the data (the nouns), we’d have a better understanding of what it was we are trying to build. Our code would be more obvious. The user’s intent would become clear. And then we could build the system the users actually want to use, the one that helps them get their work done in a more efficient fashion. The one that they don’t constantly complain about (OK, that might be a stretch…).

Model behavior by thinking about the verbs. The nouns will follow.

MassTransit and Ninject

Distributed Systems, MassTransit

My DI container of choice is Ninject. The reasons aren’t overly important, other than I hate, hate, hate XML. If I wanted to program in XML, I’d use Java. Fortunately, there are DI containers in the .Net space that don’t require all that XML, and Ninject is one of them. The Ninja connections kinda bug me, but I actually had it in my head as NINject first, so Trent trumps stupid martial arts posing.

The first thing I came across while trying to get into MassTransit, though, is that Ninject support, while advertised as existing, is a little lacking. It could just be me, but I found a problem with using any of the non-default constructors in MassTransitModuleBase, which is derived from NinjectModule. NinjectModule is the base class from which you derive to set up your bindings, and then your derived class is passed into a Ninject Kernel, which does the binding resolution. Ninject isn’t really ready to set up bindings until the Load() override in your derived class is called, but MassTransitModuleBase tries to set up bindings in the non-default constructors using the values that are passed in.

This makes sense, because the other significant non-XML based DI container, StructureMap, appears to allow this, and clearly the MassTransit guys have used that container and used it as the model for the Ninject support. Dru Sellers, one of the original authors, told me in a tweet that they weren’t all that familiar with Ninject. Its understandable – how many DI containers do you really need to know how to use?

So, I had managed to make it work by not using any of the non-default constructors at this point, because I assumed that the MassTransit implementation was correct. The result looked something like this (note that I used Mike Hadlow’s first look article as the basis for my code):

[Gist MassTransit and Ninject Example 1.cs]

   public class PlayMassTransitModule : MassTransitModuleBase

   {

       public override void Load()

       {

           base.Load();

 

           RegisterEndpointFactory(x =>

           {

               x.RegisterTransport<LoopbackEndpoint>();

               x.RegisterTransport<MulticastUdpEndpoint>();

               x.RegisterTransport<MsmqEndpoint>();

           });

 

           RegisterServiceBus(@"msmq://localhost/mt_mike_publisher", x =>

           {

               x.SetConcurrentConsumerLimit(1);

 

               ConfigureSubscriptionClient(@"msmq://localhost/mt_subscriptions", x);

           });

       }

   }

Notice that I had to set everything up in the Load() override. This is the way it has to be right now. I’m working on a patch so that you can use the Ninject container integration exactly like you do with StructureMap. Hopefully I’ll have it done and accepted by the time this post is published. In the meantime, if you want to see the full solution, check out this branch in my github DemoCode space: https://github.com/ekepes/DemoCode/tree/NinjectDemo

Getting on the Bus

Distributed Systems, MassTransit

The kinda, sorta message broker we’ve built at work over the last few years works just fine for what we are doing today. I’m actually rather proud of some of the things we’ve done with it. But the primitive pub/sub implementation I bolted on it isn’t going to do the trick going forward, as we want to have distinct services for different functional concerns. We also want to be able to use CQRS where is makes sense, but at the very least operate in an event driven manner. The current code base won’t allow that to work without a lot of change.

The world has changed since we started on the project. There are at least two solid ESB projects out there for .Net (a third depending upon what you think of the state of Ayende’s Rhino Service Bus, but I don’t think it would be responsible to depend upon a single maintainer project for something so business critical). NServiceBus is the gold standard, and rightly so – Udi Dahan is the go-to guy for all things distributed in the .Net space (and beyond). MassTransit is also a very viable project.

The problem with NServiceBus for me, at this time, is that I can’t risk having the load on the system exceed the free community version. We have entirely too many customers, and our products are sold as an on-premise solutions. We could build in the cost, no doubt, but at the moment that’s not attractive. Especially since MassTransit is proving to be just what we need. So, I’m going forward with heavily evaluating MassTransit and figuring out how to make it work for us.

One of the biggest problems with MassTransit is an absolute dearth of documentation. Some of the samples are even out of date. This seems like a good place for someone to help out, and I’ve wanted to help out on an OSS project for a long time, but couldn’t find my niche. It seems like trying to help with the documentation problem is a good use of my time, and hopefully will help me better understand how MassTransit works. So, we interrupt our previously scheduled exploration of Ruby and Rails to bring you this series on MassTransit.