NServiceBus for dummies who want to be smarties 4

NServiceBus for dummies who want to be smarties 4… fourth post, this time on how to incorporate NServiceBus as a backend in an ASP.NET MVC application.

How to create the projects

First, create a new ASP.NET MVC project. I assume you know how to use an IoC container to instantiate controllers, and that you know how to configure your container (otherwise, there are plenty of information available – e.g. here and here), so I will just show this simple snippet on how to build the bus and put it in the container:

In Application_Start:

ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(CreateWindsorContainer()));

- and then the container can be created like this:

    IWindsorContainer CreateWindsorContainer()
    {
      var container = new WindsorContainer();
 
      // register controllers and other stuff here
 
      Configure.WithWeb()
        .CastleWindsorBuilder(container)
        .XmlSerializer()
        .MsmqTransport()
          .IsTransactional(true)
          .PurgeOnStartup(true)
        .MsmqSubscriptionStorage()
        .UnicastBus()
        .CreateBus()
        .Start();
 
      return container;
    }

Notice the call to the extension method CastleWindsorBuilder? It comes from the assembly NServiceBus.ObjectBuilder.CastleWindsor.dll which is included with NServiceBus – it provides the adapters necessary for NServiceBus to a) register everything it discovers (like e.g. all your implementations of IMessageHandler<>), and b) pull instances when needed thus supplying dependencies during object activation. This way of supporting multiple IoC containers just plain ROCKS!

At this point NServiceBus has registered itself and resolved all message handlers found in the current web application’s bin directory (Configure.WithWeb() as opposed to Configure.With()) in the supplied IoC container, and since I am pulling all my controllers from Windsor, I can jump directly to implementing my HomeController:

  public class HomeController : TxBaseController
  {
    readonly IBus bus;
 
    public HomeController(IBus bus)
    {
      this.bus = bus;
    }
 
    [AcceptVerbs(HttpVerbs.Post)]
    public RedirectToRouteResult DoSomething(string text)
    {
      bus.Send(new SomethingHappened {Message = text});
 
      return RedirectToAction("Index");
    }
 
    [AcceptVerbs(HttpVerbs.Post)]
    public RedirectToRouteResult DoSomethingBad(string text)
    {
      bus.Send(new SomethingHappened { Message = text });
 
      throw new ApplicationException("oh noes!");
    }
 
    public ViewResult Index()
    {
      return View();
    }
  }

As you can see, I implemented two actions responding to a HTTP post, both sending a message to the backend, but DoSomethingBad throws an exception, in which case i do not want the message to actually be sent.

My view is just a trivial (Spark) view with two forms:

<use master="Site"/>
 
<h1>DoSomething</h1>
<form method="post" action="!{Url.Action("DoSomething")}">
  Enter text: <input type="text" name="text" />
  <input type="submit" value="Send" />
</form>
 
<h1>DoSomethingBad</h1>
<form method="post" action="!{Url.Action("DoSomethingBad")}">
  Enter text: <input type="text" name="text" />
  <input type="submit" value="Send" />
</form>

And then I made a simple backend with one message handler:

  public class HandleSomethingHappened : IMessageHandler<SomethingHappened>
  {
    public void Handle(SomethingHappened message)
    {
      Console.WriteLine("Something happened: {0}", message.Message);
    }
  }

Now, to check if things work, I navigate to /home/index, which on my computer looks like this:

dosomething

- and then I enter the text “WHEE!” into the first text field and press “Send”, yielding the following in my backend’s console window:

fantastic

Which is great! My backend receives messages from my web application, so now I can put all kinds of heavy calculations and processesing and whatnot in there, to be computed outside of web requests.

Now, what if something bad happens during the web request, and we do not want any messages to actually be sent? Well, if I enter a text into the other text field and submit it (to the DoSomethingBad action of my HomeController), nothing happens on the backend! Why is that?

Simply because I have started a TransactionScope in my controller layer supertype, TxBaseController, ensuring that all controller actions are run inside a (possibly distributed) transaction! It looks like this:

  public abstract class TxBaseController : Controller
  {
    TransactionScope currentTx;
 
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
      currentTx = new TransactionScope();
 
      base.OnActionExecuting(filterContext);
    }
 
    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
      base.OnActionExecuted(filterContext);
 
      var exceptionHappened = filterContext.Exception != null;
      var exceptionWasHandled = filterContext.ExceptionHandled;
 
      if (!exceptionHappened || exceptionWasHandled)
      {
        currentTx.Complete();
      }
 
      currentTx.Dispose();
    }
  }

- and since message queueing plays along nicely with the currently ongoing ambient transaction (which e.g. the incredible NHibernate ALSO does), this transaction scope will make sure that everything just works!

Conclusion

That concludes today’s “NServiceBus for dummies who want to be smarties”. This one was on how to actually put NServiceBus to use as a simple backend for an ASP.NET MVC web application. Freaking easy, right?! Next time I will show how to put sagas to use by implementing one of the workflows of a typical web application.

Comments Off

NServiceBus for dummies who want to be smarties 3

NServiceBus for dummies who want to be smarties 3… third post on how to do some more stuff with NServiceBus.

But where do the messages go?

Well, where did you tell the framework to send them?

The answer to this question is deferred until the last meaningful moment, i.e. the moment when the generic host starts up and reads its app.config.

How do I receive messages?

The answer is simple: use the MsmqTransportConfig section to tell NServiceBus where this service can be reached. If the specified queue does not exist, it will be created. E.g. like so:

  <MsmqTransportConfig InputQueue="client"
                       ErrorQueue="error"
                       NumberOfWorkerThreads="1"
                       MaxRetries="5" />

How do I send messages?

This question is a bit harder to answer. First, it can be specified in the UnicastBusConfig/MessageEndpointMappings element, for each message type, or for an entire assembly at a time. E.g. like so:

  <UnicastBusConfig>
    <MessageEndpointMappings>
      <add Messages="Messages" Endpoint="someService" />
      <add Messages="MessagesRootNamespace.SomeSpecificMessage, Messages" Endpoint="anotherService" />
    </MessageEndpointMappings>
  </UnicastBusConfig>

In the example above, I have configured that all messages from the assembly Messages except SomeSpecificMessage will be routed to someService, whereas SomeSpecificMessage has its own destination in the queue anotherService.

Note that this section is not required if the service is a publisher, because then it will know where to send messages because other services have subscribed, and in the process they leave the name of the queue where they can be found.

Conclusion

That concludes today’s “NServiceBus for dummies who want to be smarties”. This was about where messages go. Next post will be an example with a simple infrastructure for an ASP.NET MVC backend running on NServiceBus, accepting subscriptions from other services. It’s going to be hot!

Comments Off

NServiceBus for dummies who want to be smarties 2

NServiceBus for dummies who want to be smarties 2… second post, this time on how to do some more stuff with NServiceBus.

How to do stuff when the service starts

Make a class implement IWantToRunAtStartup, e.g. like so:

public class BuildPoolOfExpensiveObjects : IWantToRunAtStartup
{
    public void Run()
    {
        // build that pool
    }
 
    public void Stop()
    {
        // dispose it properly
    }
}

How to speed up delivery of messages that are transient in nature

If your message contents get stale after a short period of time, it makes no sense to use reliable messaging where messages are written to disk before the message queueing service attempts to deliver the messages to their destination. Therefore, to be true to the transient nature of the messages and speed up delivery, you can decorate some of your messages with the [Express] attribute. E.g. like so:

[Express]
public class SomeFrequentlyChangingValueJustChanged : IMessage
{
    public double Value { get; set; }
}

How to make messages expire after some amount of time

If you know your message content does not make sense after some period of time, say one hour, just decorate your message with the [TimeToBeReceived] attribute – e.g. like so:

[TimeToBeReceived]("01:00:00")]
public class AnotherPeriodicallyChangingValueJustChanged : IMessage
{
    public double Value { get; set; }
}

Note that the argument to the attribute must be Parseable – unfortunately C# does not allow for calling e.g. TimeSpan.FromHours(1) in the attribute initializer.

How to stop logging all kinds of noise to the console

Logging is good, but not all the time. To disable all of NServiceBus’ logging, just make your endpoint config implement the interface IWantCustomLogging and do nothing in the Init method – e.g. like so:

public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomLogging
{
    public void Init()
    {
        // ... do nothing here =)
    }
}

Conclusion

That concludes today’s “NServiceBus for dummies who want to be smarties”. This was about how to add some more life to your service. Next post will be about the question: where do the messages go?

2 comments so far, add yours

NServiceBus for dummies who want to be smarties 1

NServiceBus for dummies who want to be smarties 1… first post: on how to get started creating services with NServiceBus.

How to create messages

Creating messages with NServiceBus consists of performing the following steps:

  1. Create a new project of type “Class Library”
  2. Make the project reference all the DLLs AND NServiceBus.Host.exe from the ZIP file (“Get it now”)
  3. Create a class for each message, “tagging” each message class with the IMessage interface – see example below
public class CreateNewUserRequest : IMessage
{
    public string Username { get; set; }
}

Note that IMessage is just a marker interface, so it does not require you to implement anything.

How to create a service

Creating a service with NServiceBus consists of performing the following steps:

  1. Create a new project of type “Class Library”
  2. Make the project reference all the DLLs AND NServiceBus.Host.exe from the ZIP file
  3. Make the project reference the message DLL from above
  4. Make a class implement IConfigureThisEndpoint – see example below
  5. Make the endpoint configuration class implement either AsA_Client, AsA_Server, or AsA_Publisher
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server
{
}

How to run that service

Make each service project run the referenced NServiceBus.Host.exe inside its bin\Debug directory – e.g. CustomerService should, as its debug action, run the external program SolutionDir\CustomerService\bin\Debug\NServiceBus.Host.exe.

NServiceBus.Host.exe, referred to as “the generic host”, is actually a Windows service, that uses reflection to pick up all the assemblies that surround it, and use them to build a service.

This is why you need to implement IConfigureThisEndpoint – it’s a marker interface that tells the generic host to look for configuration in that class.

A nifty thing to do at this point, is to set your solution to debug multiple projects when you press F5 – do this by right clicking on the top node in solution explorer, select “Set startup projects…”, and make all your service projects start up when debugging.

How to do stuff in a service

Make a class in a service that implements IMessageHandler<TMessage>. This requires you to implement one function, Handle. See example below:

public class HandleCreateNewUserRequest : IMessageHandler<CreateNewUserRequest>
{
    public void Handle(CreateNewUserRequest message)
    {
        // ..... do stuff
    }
}

But how does the service get access to the bus?

NServiceBus defaults to using Spring for DI, so dependencies are automagically resolved – which also includes the bus! Which in turn means that the following code snippet can send messages by using the bus:

public class HandleCreateNewUserRequest : IMessageHandler<CreateNewUserRequest>
{
    public IBus Bus { get; set; }
 
    public void Handle(CreateNewUserRequest message)
    {
        Bus.Send(new DoSomethingSomewhere());
    }
}

Ok, but where does the message go?

Well, that depends – for this stuff to run, we need to do a tad more configuration by supplying each service with an app.config. E.g. like so:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
    <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
  </configSections>
 
  <MsmqTransportConfig InputQueue="client"
                       ErrorQueue="error"
                       NumberOfWorkerThreads="1"
                       MaxRetries="5" />
 
  <UnicastBusConfig>
    <MessageEndpointMappings>
      <add Messages="Messages" Endpoint="server" />
    </MessageEndpointMappings>
  </UnicastBusConfig>
</configuration>

In this XML file, I am configuring the following things:

  • The MsmqTransportConfig section tells the generic host that this service can be reached at client, which is just the name of a private message queue, which the framework will automatically create for us
  • The UnicastBusConfig/MessageEndpointMappings section tells the framework that all message types from the assembly Messages should be sent to the message queue server

Please pay some respect and awe to the MaxRetries, ErrorQueue, and NumberOfWorkerThreads attributes – how cool is that?! It means that all exceptions that may happen inside your message handlers should not be handled by you, just let them bubble up to the framework and let it retry delivery up to 5 times until successful, or else the message will go to the error queue. That totally rids you of handling those pesky exceptions coming from your database transaction (hopefully rarely, or else your database is a bottleneck) being selected as the deadlock victim, temporarily unavailable external services unable to communicate, etc. Handling those things is truly the job of a framework.

Conclusion

That concludes today’s “NServiceBus for dummies who want to be smarties”. This was how to go about creating a simple service which is capable of receiving a message, and in the message handler it can send a message.

One comment so far, add another

ReSharper 5 and ASP.NET MVC goodies

I have probably only scratched the surface of the goodies that JetBrains have added to the new ReSharper 5, but here’s two nifties I discovered today: F12 jumps from the redirect string to the corresponding action method in my controller (the light arrow), and F12 on a view result method gives me the ability to jump to the corresponding view (the gray arrow). That’s just neat!

resharper_aspnet_mvc

Comments Off

Note to future self about R# and keyboard shortcuts

Did you ever sit with Visual Studio and R# writing tests, wondering if you could run tests without touching your mouse? I did that all the time, until I found out that you could go to Tools => Options => Environment => Keyboard and filter the list by “Resharper.Resharper_Unit”, giving access to keyboard shortcuts to run the current test context, debug the current test context + more.

resharper_keyboard_shorts

I have assigned Ctrl + Alt + Enter to run my current test context and Shift + Ctrl + Alt + Enter to run my current test session.

Comments Off

R# FTW

Recently I made a post because I was experiencing a moment of silent awe with R#.

R# 5 is on its way, and the feature list is impressive! I am excited about the call and value tracking features, because that’s basically all I do in one particular huge legacy system I am working on.

I am going to wait a few days, and then I will download one of the nightly builds and go check it out – I almost cannot wait!

Comments Off

Soon, it’s JAOO time…

…and it’s going to be great!

I am looking forward to too many presentations to mention! My only limitation is that I am confined to the “Programming languages” track on Monday afternoon, because I am supposed to function as a track manager there, so unfortunately I will miss the CouchDB from 3333 km presentation.

The rest of the time, however, I will check out all kinds of great presentations. But what I like the most, is that I am always filled with inspiration and creative drive after attending JAOO.

See you there!

One comment so far, add another

Fluent NHibernate automapping and cascading

One of the things you usually end up wanting to configure on a case-to-case basis when using NHibernate is cascading – i.e. which relations should NHibernate take responsiblity for saving.

An example could be in DDD terms where you have an aggregate root, that contains some stuff. Let’s take an example with a Band which is the subject of the BandMember role, which in turn references another aggregate root, User, that is the object of the band member role.

It is OK for us that we need to save a User and a Band in a repository, that’s the idea when dealing with aggregate roots. But everything beneath an aggregate root should be automatically persisted, and the root should be capable of creating/deleting stuff beneath itself without any references to repositories and stuff like that.

So how do we do that with NHibernate? Well, it just so happens that NHibernate can be configured to cascade calls to save, delete, etc. through relations, thus allowing the aggregate root to logically “contain” its entities.

This is all fine and dandy, but when Fluent NHibernate is doing its automapping, we need to be able to give some hints when we want cascading to happen. I usually want to be pretty persistence ignorant, BUT sometimes I just want to be able to do stuff quickly and just get stuff done, so I usually end up “polluting” my domain model with a few attributes that give hints to a convention I use.

Consider this:

public class Band : EntityBase
{
	public Band()
	{
		BandMembers = new List<BandMember>();
	}
 
	public virtual string Name { get; set; }
 
	[Cascade]
	public virtual IList<BandMember> BandMembers { get; set; }
 
	public virtual void AddBandMember(User user, BandMemberType bandMemberType)
	{
		var bandMember = FindExistingBandMember(user) ?? new BandMember(user);
		bandMember.BandMemberType = bandMemberType;
	}
 
	public virtual void RemoveBandMember(User user)
	{
		BandMembers.Remove(FindExistingBandMember(user));
	}
 
	BandMember FindExistingBandMember(User user) 
	{
		return BandMembers.ToList().Find(b => b.User == user);
	}
}
 
public enum BandMemberType 
{
	Member, Administrator
}
 
public class BandMember : EntityBase
{
	public BandMember(User user)
	{
		User = user;
	}
 
	public virtual BandMemberType BandMemberType { get; set; }
 
	public virtual User User { get; set; }
}
 
public class User : EntityBase
{
	public virtual string Name { get; set; }
}

Notice that little [Cascade]-thingie in there? It’s implemented like this:

public class CascadeAttribute : Attribute
{
}

Trivial – but I want that to be spotted by Fluent NHibernate to make the BandMembers collection into a cascade="all-delete-orphan", which in turn will cause the methods AddBandMember and RemoveBandMember to be able to update the DB.

I do this with a CascadeConvention, which is my implementation of the IHasManyConvention and IReferenceConvention interfaces. It looks like this:

public class CascadeConvention : IHasManyConvention, IReferenceConvention
{
	public void Apply(IManyToOneInstance instance)
	{
		var property = instance.Property;
 
		if (!HasAttribute(property)) return;
 
		Console.WriteLine("CascadeAll on {0}.{1}", property.DeclaringType.Name, property.Name);
 
		instance.Cascade.All();
	}
 
	public void Apply(IOneToManyCollectionInstance instance)
	{
		var property = instance.Member;
 
		if (!HasAttribute(property)) return;
 
		Console.WriteLine("CascadeAllDeleteOrphan on {0}.{1}", property.DeclaringType.Name, property.Name);
 
		instance.Cascade.AllDeleteOrphan();
	}
 
	bool HasAttribute(ICustomAttributeProvider provider)
	{
		return provider.GetCustomAttributes(typeof(CascadeAttribute), false).Length == 1
	}
}

What is left now is to make sure Fluent NHibernate picks up my convention and uses it. I usually do this by throwing them into the same assembly as my entities and do something like this when configuring FNH:

new AutoPersistenceModel()
        // (...)
        .Conventions.Setup(s => s.AddFromAssemblyOf<EntityBase>())
        .Configure(configuration);

- which will cause all conventions residing in the same assembly as EntityBase to be used.

This works really good for me, because it makes it really easy and quick to configure cascading where it’s needed – I don’t have to look deep into an .hbm.xml file somewhere or try to figure out how cascading might be configured somewhere else – the configuration is right where it’s relevant and needed.

Extremist PI-kinds-of-guys might not want to pollute their domain models with attributes, so they might want to use another way of specifying where cascading should be applied. Another approach I have tinkered with, is to let all my entities be subclasses of an appropariate base class – like e.g. AggregateRoot (implies no cascading), Aggregate (implies cascading), and Component (implies that the class is embedded in the entity).

The great thing about Fluent NHibernate is that it’s entirely up to you to decide what kind of intrusion offends you the least :)

3 comments so far, add yours

It’s just annoying that Joel Spolsky is such is great writer…

…because I almost never agree with him!

For instance, in this post – inspired by the book, Coders At Work – he describes the character he calls “the duct tape programmer”, who is the archetype of that annoyingly great programmer, who just seems to be able to solve any kind of problem with only a few tools.

One of the attributes of “the duct tape programmer” is that he seldomly wastes time writing tests, because “(…) the customer isn’t going to complain about that”. Another is that he does not succumb to hype and trends in software development, he is confident that what he knows is enough.

And so Joel goes, on and on about this fantastic programmer, who’s capable of delivering what the customer wants without all the fancy hypes brand-spanking-new technologies and methodologies that all the other programmers seem to waste their time with.

The problems, as I see it, are: a) Very few programmers are like that (you know, that Linus Torvals/Bjarne Stroustrup kind of guy), and b) I will NEVER be the guy who maintains his code!

The thing is – to continue Joel’s analogy – that “the duct tape programmer” might be able to win a go-cart race with a go-cart made of duct tape and WD-40, but I would NOT trust him to make a car for me to drive on the highways! – because I would not expect that car to be safe at high speed, and I would not expect it to last for years, and I would not expect it to withstand rain, snow, sand, etc.

In my opinion, automated unit tests and integration tests serve many purposes. One (obvious) one is to continually verify the behavior of a system, given that implementations may change and bugs be fixed and so on. Another is to DOCUMENT the behavior of the system, like in “we agreed with the customer that it should work like this”. Yet another is to aid the programmer while writing his code into separating concerns, because doing that just causes less pain when writing tests. Joel should stop bashing TDD.

And when it comes to new technologies and methodologies, I think it is SO IMPORTANT to keep an eye open for new AND old better ways to do stuff. My opinion is that I get smarter all the time by keeping an open eye on what other people are thinking and doing, and I get smarter all the time by putting some of it to use. Joel is just annoying here, because his statements lack nuance – keeping up with new stuff is NOT the same as bringing in new stuff unconsciously, but Joel does not seem to be capable of drawing this distinction.

In my opinion, there is no place for “the duct tape programmer” on a team. At least not on my team.

So if you care about your teammates, about the quality AS WELL AS THE MAINTAINABILITY AND EXPLAINABILITY of your code, please DO write tests!

And please DO separate concerns and take the time to factor out stuff into easy-to-understand narrow and focused classes!

And please, please DO use new as well as old technologies and practices where it makes sense – don’t put stuff off because it’s new, and you are used to hand-rolling your own linked lists and string structs in C and the C++ STL is just another fancy new hype to you.

Comments Off