Finding a common namespace root for an assembly

“What’s the difference between a namespace and an assembly?”

It’s a very standard interview question and I’m sure we can all answer that one easily.  And so we all know that it’s possible for an assembly to contain types from a variety of namespaces and that these namespaces may or may not have anything in common with each other.

But in the real world, types within an assembly typically do have something in common with each other.  And usually there is a common portion of the namespace names.  And in case you want to work out what that common portion is, here is some code:

public static class AssemblyHelper
{
    public static string DeduceRootNamespaceParts(Assembly assembly)
    {
        var splitNamespaces = assembly.GetTypes()
            .Where(type => type.IsPublic)
            .Select(type => type.Namespace.Split('.'))
            .ToArray();

        var largestCommonality = 0;

        do
        {
            if(largestCommonality >= splitNamespaces[0].Length)
                break;

            var valueToTest = splitNamespaces[0][largestCommonality];
            var commonality = largestCommonality;
            var areAllSame = splitNamespaces.All(strings => strings.Length > commonality && strings[commonality] == valueToTest);
            if(!areAllSame)
                break;
            largestCommonality++;
        } while (true);

        return String.Join(".", splitNamespaces[0].Take(largestCommonality).ToArray());
    }
}

I suspect that this code is O(n) complexity with regard to the number of types contained in the assembly, but I haven’t thought about it terribly deeply.

April 28 2010

NBehave: Executing a Scenario

NBehave can initially very strange to developers … after all, the idea of “executing” a text file is simply foreign.  So here’s a brief run-down of how NBehave works. Let's suppose we have the following scenario file:

Given I have entered 1 into the calculator
And I have entered 2 into the calculator
When I add the numbers
Then the sum should be 3

NBehave processes this line-by-line.  So it picks up "Given I have entered 1 into the calculator" and will try to match this against a suitable method.  Classes that can provide such methods are attributed with [ActionSteps].  Let’s suppose the NBehave locates the following class:

[ActionSteps]
public class AddNumbers
{
    private Calculator _calculator;

    [BeforeScenario]
    public void SetUp_scenario()
    {
        _calculator = new Calculator();
    }

    [Given(@"I have entered $number into the calculator")]
    public void Enter_number(int number)
    {
        _calculator.Enter(number);
    }

    [When(@"I add the numbers")]
    public void Add()
    {
        _calculator.Add();
    }

    [Then(@"the sum should be $result")]
    public void Result(int result)
    {
        _calculator.Value().ShouldEqual(result);
    }
}

So NBehave matches our line of text to the following method, using the regular expression in the [Given] attribute:

[Given(@"I have entered $number into the calculator")]
public void Enter_number(int number)
{
    _calculator.Enter(number);
}

The value of 1 is captured by the regex from the text string, so NBehave calls "Enter_number(1)".  Well actually, since this is the very first step in the scenario NBehave first looks for a [BeforeScenario] attribute and so "SetUp_scenario()" will be executed before "Enter_number(1)".

The next line of the scenario "And I have entered 2 into the calculator" is matched to the same method ("And" is treated as equivalent to "Given" in this case) and so "Enter_number(2)" gets executed.

And so on and so on.  So overall, the scenario:

Given I have entered 1 into the calculator
And I have entered 2 into the calculator
When I add the numbers
Then the sum should be 3

will get translated into:

var calc = new AddNumbers();
calc.SetUp_scenario();
calc.Enter_number(1);
calc.Enter_number(2);
calc.Add();
calc.Result(3);

The final result, which I hope is now clear, is that the scenario file is really just a human-readable way of expressing code!

April 24 2010

Silverlight duplex communication, part 1

Somebody recently asked me about duplex communications with Silverlight clients (i.e. pushing data out to the client application) and it made me realise that I needed to brush up on some of the basic detail. So I put together a little learning project, and it's something I'd like to share.

Note this has been built with the RC of VS 2010 and SL 4.0.

Network Communications in Silverlight

Mike Taulty has put together a great series of Channel 9 videos where he does a whistle-stop tour of the various network options available within SL 4. Simply put, the main ones are:

  • WCF over HTTP
  • WCF over TCP
  • TCP sockets
  • UDP sockets
  • WebRequest over HTTP

My application will use the two WCF options to implement a real-time chat application, although currently only the duplex HTTP binding is implemented.  Here is a screenshot of it in action, showing two browser windows communicating in real-time:

 image

Architecture of my Sample Application

The Silverlight portion of the application is pretty simple and uses the NavigationFrame (introduced in SL 3) and if you've played with the Silverlight Navigation Application template then you should be fairly familiar with the project layout. The important view is PollingDuplexHttpClient.xaml.

When using the MVVM pattern (which I am) there are a number of ways of hooking the ViewModel into the view (reference). I'm using a simple XAML-based approach to set the DataContext of the Page to the ViewModel:

   1: <navigation:Page.DataContext>
   2:   <app:DuplexHttpClientViewModel />
   3: </navigation:Page.DataContext>

The ViewModel class itself derives from an abstract base class DuplexChatClientViewModelBase. The sole purpose of the concrete ViewModel classes is to specify the actual WCF binding to use (net.tcp or http). And the primary purpose of the base ViewModel class is to co-ordinate the services which do the real work.

There’s a couple of aspects to the application which I think are interesting.  I hope to be posting some further detail on these in future.

Doing the Duplex Communication

The WCF communication is handled in the asynchronous manner typical of Silverlight, and is contained in the PushDataReceiver class.  There are four separate chains of execution in this class:

  • EnsureStarted –> OnOpenCompleteFactory –> CompleteOpenFactory –> OnOpenCompleteChannel –> CompleteOpenChannel
  • Send –> OnSendComplete –> CompleteSend
  • Receive –> OnReceiveComplete –> CompleteReceive
  • Close –> OnCloseComplete –> CompleteClose

Obviously the first and last of these are only called once, whereas the Send and Receive chains are more frequently executed.  The sending operation does not need much explanation:

   1: public void Send(Message message)
   2: {
   3:     IAsyncResult resultChannel = channel.BeginSend(message, new AsyncCallback(OnSend), channel);
   4:  
   5:     if (resultChannel.CompletedSynchronously)
   6:         CompleteOnSend(resultChannel);
   7: }
   8:  
   9: private void OnSend(IAsyncResult result)
  10: {
  11:     if (result.CompletedSynchronously) return;
  12:     CompleteOnSend(result);
  13: }
  14:  
  15: private void CompleteOnSend(IAsyncResult result)
  16: {
  17:     var sendingChannel = (IDuplexSessionChannel) result.AsyncState;
  18:     sendingChannel.EndSend(result);
  19: }

The receiving operation is similar in structure, with the exception that it is recursive and it needs to actually do something with the incoming message.  It is first initiated by the CompleteOpenChannel method

   1: private void ReceiveLoop(IDuplexSessionChannel receivingChannel)
   2: {
   3:     if (receivingChannel.State == CommunicationState.Opened)
   4:     {
   5:         IAsyncResult result = receivingChannel.BeginReceive(new AsyncCallback(OnReceiveComplete), receivingChannel);
   6:         if (result.CompletedSynchronously) CompleteReceive(result);
   7:     }
   8: }
   9:  
  10: private void OnReceiveComplete(IAsyncResult result)
  11: {
  12:     if (result.CompletedSynchronously) return;
  13:     CompleteReceive(result);
  14: }
  15:  
  16: private void CompleteReceive(IAsyncResult result)
  17: {
  18:     var receivingChannel = (IDuplexSessionChannel) result.AsyncState;
  19:  
  20:     Message receivedMessage = receivingChannel.EndReceive(result);
  21:  
  22:     if (receivedMessage != null)
  23:         uiThread.Post(ServiceLocator.Processor.ProcessData, receivedMessage); // Run on UI Thread.
  24:     ReceiveLoop(receivingChannel);
  25: }

Line 33 in the above code snippet is where the recursion happens to ensure that we always wait for incoming data.  Please note that exception handling code has been omitted here for the sake of clarity … it is present in the code download!  ;-)

Now all this seems very clear and straightforward, except for the fact that the server has no way of knowing that we are actually listening.  And this is why the service exposes an InitiateDuplex method.  From the CompleteOpenChannel method, we call Send against this service method.  It is this method which obtains a reference to the back channel to the SilverLight client.

I plan to run some deeper analysis into what’s actually happening on the wire.  Check back here soon for some details.

The WCF Service

There’s some surprising stuff going on in the service implementation here - a timer to keep channels alive, recording of IP addresses and timestamps, etc – but the most important bits are in the service contract (which is attributed to have a CallbackContract) and the InitiateDuplex method.  Here the code is building up a list of clients that will be sent any incoming message:

   1: public void InitiateDuplex(Message receivedMessage)
   2: {
   3:     lock (clients)
   4:     {
   5:         localClient = OperationContext.Current.GetCallbackChannel<IChatRoomClient>();
   6:         clients.Add(localClient);
   7:     }
   8: }

The code which uses the list of back channels is the DispatchToClientsmethod, which gets called whenever a client pushes a message to the SendMessage service method:

   1: private void DispatchToClients(ChatData data)
   2: {
   3:     var clientsToRemove = new List<IChatRoomClient>();
   4:     lock (clients)
   5:     {
   6:         foreach (IChatRoomClient client in clients)
   7:         {
   8:             try
   9:             {
  10:                 //Send data to the client
  11:                 if (client != null)
  12:                 {
  13:                     Message chatMsg = Message.CreateMessage(MessageVersion.Soap12WSAddressing10,
  14:                                                             "Silverlight/IChatRoomService/Receive",
  15:                                                             data,
  16:                                                             serializer);
  17:  
  18:                     chatMsg.Headers.Add(MessageHeader.CreateHeader("Type", "", "DataWrapper"));
  19:                     client.BeginReceive(chatMsg, EndSend, client);
  20:                 }
  21:             }
  22:             catch (Exception)
  23:             {
  24:                 // Exception caught when trying to send message to client so remove them from client list.
  25:                 clientsToRemove.Add(client);
  26:             }
  27:         }
  28:  
  29:         foreach (IChatRoomClient client in clientsToRemove)
  30:         {
  31:             clients.Remove(client);
  32:         }
  33:     }
  34: }

FYI a lot of this code comes fairly directly from Dan Wahlin’s post about duplex communications.

Caveat: the server delivers message to the listed clients one-by-one.  This means that delivery will slow down with the number of connected clients.

Getting Running

If you want to get this running on your machine you will need Visual Studio 2010 RC.  The steps you need to follow are pretty simple to enable HTTP communications:

  • Download the code
  • Build everything in Visual Studio and hit F5 to start the SilverlightTestBed.Web project and the WCF service.

Future Posts

I plan to post a few more articles about this application:

  • Analysing HTTP traffic and communication patterns
  • Enabling net.tcp communication
  • Analysing what that looks like on the wire
  • Refactoring the code to use Rx (Reactive Extensions for .Net)
April 13 2010

NBehave: Different ways to drive BDD tests / specs

My last post introduced NBehave and BDD as a natural evolution of unit testing.  Here I will show you the different ways in which you can express a spec using NBehave.

1. With Inline Lambdas

This is how I finished my previous post:

   1: [TestClass]
   2: public void CalculatorTests : ScenarioDrivenSpecBase
   3: {
   4:     // CreateFeature omitted for clarity
   5:  
   6:     [TestMethod]
   7:     public void Add_RepeatedAddition_CheckThatThreeTriesDoNotFail()
   8:     {
   9:         Calculator calc = null;
  10:  
  11:         Feature.AddScenario()
  12:             .Given("a calculator",        () => calc = new Calculator())
  13:             .And("I have added 10",       () => calc.Add(10))
  14:             .And("I have added 10 again", () => calc.Add(10))
  15:             .When("I add another 10",     () => calc.Add(10))
  16:             .Then("the sum should be 30", () => Assert.AreEqual(30, calc.Result));
  17:     }
  18: }

This syntax is bearable for small lamba expressions, although you do usually end up fighting Visual Studio and Resharper to maintain the nice code layout.  This style also does not really promote reuse of the step definitions.

2. With the Steps in Suitably Named Methods

Here we pull the code out of lambda expressions and elevate it into methods.  Methods are located via reflecting on the object passed in on line 12 below.

   1: [TestClass]
   2: public void CalculatorTests : ScenarioDrivenSpecBase
   3: {
   4:     // CreateFeature omitted for clarity
   5:  
   6:     [TestMethod]
   7:     public void Add_RepeatedAddition_CheckThatThreeTriesDoNotFail()
   8:     {
   9:         Calculator calc = null;
  10:  
  11:         Feature.AddScenario()
  12:             .WithHelperObject<CalculatorSpecificationSteps>()
  13:             .Given("a calculator")
  14:             .And("I have added 10")
  15:             .And("I have added 10")
  16:             .When("I add another 10")
  17:             .Then("the sum should be 30");
  18:     }
  19: }
  20:  
  21: public class CalculatorSpecificationSteps
  22: {
  23:     private Calculator _calculator;
  24:  
  25:     protected void Given_a_calculator()
  26:     {
  27:         _calculator = new Calculator();
  28:     }
  29:     
  30:     protected void And_I_have_added_10()
  31:     {
  32:         _calculator.Add(10);
  33:     }
  34:     
  35:     protected void When_I_add_another_10()
  36:     {
  37:         _calculator.Add(10);
  38:     }
  39:     
  40:     protected void Then_the_sum_should_be_30()
  41:     {
  42:         Assert.AreEqual(30, calc.Result);
  43:     }    
  44: }

The helper class can be the same class that holds your spec, or a base class, or a completely separate class altogether.  This style has better readability of the spec and also allows you to build up a “vocabulary” of reusable steps.  On the downside, it does constrain your method names.

3. With the Steps in Attributed Methods

We all know that loose coupling is a good thing, and our code may be better if we could differentiate our method names from their longer description.  We can do this by using attributes that contain regular expressions:

   1: [TestClass]
   2: public void CalculatorTests : ScenarioDrivenSpecBase
   3: {
   4:     // CreateFeature omitted for clarity
   5:  
   6:     [TestMethod]
   7:     public void Add_RepeatedAddition_CheckThatThreeTriesDoNotFail()
   8:     {
   9:         Calculator calc = null;
  10:  
  11:         Feature.AddScenario()
  12:             .WithHelperObject<CalculatorSpecificationSteps>()
  13:             .Given("a calculator")
  14:             .And("I have added 10")
  15:             .And("I have added 10")
  16:             .When("I add another 10")
  17:             .Then("the sum should be 30");
  18:     }
  19: }
  20:  
  21: [ActionSteps]
  22: public class CalculatorSpecificationSteps
  23: {
  24:     private Calculator _calculator;
  25:  
  26:     [Given(@"a calculator")]
  27:     protected void SetupCalculator()
  28:     {
  29:         _calculator = new Calculator();
  30:     }
  31:     
  32:     [Given(@"I have added $number")]
  33:     [When(@"I add another $number")]
  34:     protected void Add(int number)
  35:     {
  36:         _calculator.Add(number);
  37:     }
  38:     
  39:     [Then(@"the sum should be $result")]
  40:     protected void ValidateResult(int result)
  41:     {
  42:         Assert.AreEqual(result, calc.Result);
  43:     }    
  44: }

So here I’ve used the same method for my given and my when clauses by applying two attributes.  I’ve also made use of NBehave’s ability to use regex captures to extract parameter values.  Very cool IMHO.

4. With the Scenario in an External File

In this style of spec, we put the following into a separate file (typically with a .scenario extension) and we still have the CalculatorSpecificationSteps class above:

   1: Feature: arithmetic addition
   2:  
   3: Scenario: Add numbers
   4:     Given a calculator
   5:     And I have added 10
   6:     And I have added 10
   7:     When I add another 10
   8:     Then the sum should be 30

We can then use the NBehave runner to execute this spec.  By this stage, you have probably worked out that this involves line-by-line parsing of the scenario and matching against attributed methods.

With this style of spec we have the best possible separation of intent and implementation and the readability of the specification is superb.  There is no code, funky punctuation, “dagger operators” or other cruft to try and ignore.  The downside is the need for a custom test runner (although NAnt and MSBuild tasks are provided) and a current lack of integration with TestDriven.Net and the Resharper test runner.

5. With a Table-based Scenario

The best way to think of this is as a data-driven specification.  And the best way to explain is by an example.  We take the external file above and modify as follows:

   1: Feature: arithmetic addition
   2:  
   3: Scenario: Add numbers
   4:     Given a calculator
   5:     And I have added [num1]
   6:     And I have added [num2]
   7:     When I add another [num3]
   8:     Then the sum should be [result]
   9:  
  10: Examples:
  11: |num1|num2|num3|result|
  12: |10|10|10|30|
  13: |20|20|20|60|
  14: |15|8|3|26|

This file actually represents 3 scenarios, and each scenario will get executed separately.  The values in the “Examples” section will get substituted into the scenario steps and eventually passed into the methods on the CalculatorSpecificationSteps class.

This approach allows us to very quickly and easily create a number of scenarios that differ only in the values being used, although perhaps at the expense of some readability.

Which one to use?

General advice is, of course, generally wrong and so I’m going to try hard not to give any.  However, if you develop an attributed ActionSteps class then it can be used in styles #3, #4 and #5.  Styles #4 and #5 also provide some ready-made human-readable documentation about your application and it’s possible that htye can be authored by a non-dev.  If there are reasons why you can’t (or don’t want to) use a custom test runner, then style #3 will is entirely compatible with  your test framework of choice (NUnit, MBUnit, Xunit or MSTest).

PS. only style #4 is available in NBehave v0.45.  The rest are available currently on the trunk and will be included in NBehave v0.5.

April 8 2010
Newer Posts Older Posts