Pex
Looks like Pex is out and ready for us to play with, seems like interesting stuff and as well as Peli posting up links to docs you can also view Ben Hall's first impressions.
In addition it looks like MbUnit can already be used with it.
Technical blog.
Looks like Pex is out and ready for us to play with, seems like interesting stuff and as well as Peli posting up links to docs you can also view Ben Hall's first impressions.
In addition it looks like MbUnit can already be used with it.
Posted by Colin Jack at 5/29/2008 0 comments
Pat Maddox has a superb post called Refactoring with Shared Example Groups which describes one strategy that Ruby programmers can consider when deciding how they want to change their tests when they extract a class/method in the SUT.
I'd guess you could use a similar solution in C# especially if you hooked into a test framework like Gallio, mind you it might be equally sensible to look at IronRuby for testing (longer term).
Posted by Colin Jack at 5/15/2008 0 comments
Labels: Ruby, TDD, Unit Testing
Discussions at ALT.NET and with Greg Young made me realize that I need to get more into messaging so I thought I’d start with a piece of work I’m doing now that is ripe for a bit of messaging. The piece of work relates to domain events, when an event happens in the domain (e.g Customer becomes active) we generate a message which subscribers can pick up. Generating an MSMQ message and sending it to subscribers seems sensible.
The obvious framework to look at was NServiceBus but Mass Transit is an alternative which I decided to try. Whilst playing with it I thought I'd write up my discoveries in the hope that someone might be useful and also produced a little sample project which you can download here.
First I should add some caveats:
Note that this sample contains a copy of some the Mass Transit code, I've done this to make it easier to setup/debug but the code will quickly go out of date so it is certainly worth downloading the latest copy.
If you want to run the different parts of the example then you can do so using the binaries in the TestAppBinaries folder. The parts of the solution are:
Debugging wise I found I could only really follow one app at a time, so I might start SubscriptionManager and Receiver and then debug Sender and then check that it correctly finds out about and processes the fact that Receiver wants to know about FootbalResultMessages.
Currently you must start the Receiver before the Sender or the behaviour will not be as expected, I will look into the reasons for this.
The world revolves around the ServiceBus class which has several methods that you can use to send messages:
Send/Deliver are fine and I do use them but they do not promote truly loose coupling, in many cases you won't want to specify the destination when sending the message and so I’m really more interested in Publish. You can see this if you look at Sender class (well its a static Main method, but hey this is just sample code) as it contains the following line:
bus.Publish(new FootballResultMessage(message))To understand the way that the Publish approach works you need you need to look at how the ServiceBus manages subscriptions...
I'll explain one potential way of handling these two parts using Mass Transit.
Adding/Removing Subscriptions (Receiver)
A subscriber sends an AddSubscription message to the ServiceBus when it wants to subscribe to a particular kind of message. The AddSubscription message takes two parameters, the message name and the URI (which in our case means MSMQ queue) to send messages of that type to.
To see how this works look at SubscriptionBasedMessageProcessor, in the Subscribe method it registers its interest in the message type that it is setup with. This registration involves the AddSubscription message being sent to the SubscriptionManager. In addition we specify a delegate (callback) that will be run when a message of the specified type arrives.
The code that sends the AddSubscription message is in MsmqUtil:
private static void SendSubscription(ServiceBus bus)
{
AddSubscription subscriptionMessage = new AddSubscription(MessageName, bus.Endpoint.Uri);
SendSubscriptionUpdate(bus, subscriptionMessage);
}
private static void SendSubscriptionUpdate(ServiceBus bus, SubscriptionChange subscriptionMessage)
{
MsmqEndpoint publishersQueue = "msmq://./subscriptions";
bus.Send(publishersQueue, subscriptionMessage);
}
You can see that in this case I'm sending an AddSubscription message to the central subscription management queue saying that football result messages should be sent to the ServiceBus that is passed in (which is the same queue that the BasicMessageReceiver is listening on).
Managing Subscriptions (SubscriptionManager)
My centralized store needs to maintain the list of subscriptions and also provide a way for interested parties to find out about them:
Since all I needed was in-memory supported I used LocalSubscriptionCache. Not that I had to make LocalSubscriptionCache implement ISubscriptionRepository so that I could use it with SubscriptionService, however this was a trivial change. The code that registers the cache is:
LocalSubscriptionCache cache = new LocalSubscriptionCache();
ServiceBus bus = new ServiceBus(subscriptionQueue, cache);
SubscriptionService subscriptionService = new SubscriptionService(bus, cache, cache);
subscriptionService.Start();
To see this code at work put a break point in MsmqMessageReceiver.ProcessMessage, start SubscriptionManager in the debugger and then open Sender which causes a cache update request message to come in for processing. You should end up debugging into SubscriptionService.HandleCacheUpdateRequest which ensures the appropriate response is sent back to the caller.
One interesting thing to note is that when Sender sends off the CacheUpdateRequest it puts the return address as its own ServiceBus' end point (the MSMQ queue it is working from). The reply message is picked off this queue by MsmqMessageReceiver and is then routed to the SubscriptionClient which has registered its interest in the reply.
Requesting Subscriptions (Sender)
I've now managed to get my subscriptions registered with a centralized queue (backed up by SubscriptionManager), however I need to make sure that I can get the latest subscriptions when I need them. Luckily this is easily accomplished using the SubscriptionClient:
SubscriptionClient subscriptionClient = new SubscriptionClient(bus, bus.SubscriptionCache, subscriptionServiceEndpoint);
subscriptionClient.Start();
This class ensures that I am kept up to date as subscriptions are updated, for example if an AddSubscription is processed by the centralized service then it will be distributed back to my service which will cause SubscriptionClient.CacheUpdateResponse_Callback to execute (NOTE: I'm not sure I've fully understood this functionality yet and it is not working quite as I expected so this last statement may not be correct).
One key thing I learned when working on this was how key the queue that you pass into a ServiceBus on construction is, this queue is the one that the ServiceBus looks for messages on.
To see how key it is you can write a simple code example and follow it through. Create a ServiceBus then call Subscribe and pass in any old delegate before publishing a message of the same type using Publish.
When you run the code you can see a few things:
This setup makes a lot of sense as the behaviour is the same regardless of the messages origin, so a message coming into the ServiceBus’ queue from outside is treated the same as a message that the ServiceBus adds to its own queue.
Posted by Colin Jack at 5/05/2008 0 comments
Labels: Design, Mass Transit, Messaging