BLOG

.NET 4.0 - The Game Changers (In My Opinion)

27 May 2009 by Stuart Cam

If you haven't yet noticed .NET 4.0 and Visual Studio 2010 are out of CTP and into Beta. Bleeding-edge developers might want to download and take them for a spin.

There are quite a few new features in .NET 4.0, the most interesting for me are:

  • Task Parallel Library (TPL). Now a first class citizen in the framework, the Parallel FX (PFX) library makes writing multithreaded code a breeze. I had the opportunity to attend a talk on the PFX library with Joe Duffy at TechEd, Sydney 2008 . It's nice to see this library finally make it into the BCL.
  • Dynamic Language Runtime (DLR). Dynamic languages, such as IronPython and IronRuby, now make 'official' status in the .NET framework. C# implements a new dynamic keyword to interop with dynamic languages. Here is a great video on Channel 9 with Eric Lippert and the C# compiler developers where they talk about C#'s static viewpoint on dynamic typing.
  • Code Contracts & Pex. Remember Spec#? the superset of C# with design-by-contract features? Well, the team in Microsoft Research have decided to bundle all of the idioms into a .NET library, welcome the new namespace System.Diagnostics.Contracts. This video at PDC 2008 gives a great overview of C# design-by-contract programming, and a wonderful demonstration of Pex. Download Code Contracts for Visual Studio 2008.

The IDE is also gradually making the transition to WPF making the whole visual experience a lot more pleasing. I wonder how far the customisation will be taken?

.NET 4.0 doesn't quite have the same impact on me (personally) that .NET 3.5 had (I am still blown away by just how powerful and brilliant LINQ is). That said it's really exciting to see Microsoft taking the framework forward and offering their take on the future of Windows programming. Take a look at how .NET is changing.

Tags: , , ,

Categories: .NET | C Sharp

Mocking A Generic Method And Generic Constraint

14 May 2009 by Stuart Cam

I just stumbled across a problem in my integration testing around a particular scenario.

The problem occurs when attempting to create a mock instance for a class that has a generic method with a generic constraint - either at the class or method level.

Consider the following code:

public interface IFoo<T> where T : IBar
{
  T Get();
}

We have added a constraint to the interface IFoo such that T must implement IBar. So far so good, apart from the 'standard' Rhino Mocks code below throws an exception:


public class MyBar : IBar {
  //...
}

//...

var mockInstance = Mocks.DynamicMock<IFoo<MyBar>>();

This fails with an error:

System.TypeLoadException: Access is denied: 'IFoo`1[MyBar]'.

The problem is that the underlying BCL has a bug in Reflection Emit which causes it to generate invalid code. Oh dear. This has already been raised as an issue with MS - but they are failing to resolve it. Go and make your feelings heard!

Ayende has a workaround in Rhino Mocks 3.4 and above, so now you can write the following:

var mockInstance = Mocks.DynamicMockWithRemoting<Foo<MyBar>>();

This pushes the creation of the mock object through some additional hoops to bypass the BCL bug. Smart!

Tags: , ,

Categories: .NET | C Sharp | TDD

C# Distance Between Two Post Codes

08 May 2009 by Stuart Cam

Google provides a fantastic Map API to retrieve address information for a particular post code (zip code to our fellow Americans).

I needed to calculate the distance between two UK post codes, and stumbled across a handy URL for querying Google:

http://maps.google.com/maps/geo?q=SW1A%202AA&output=xml

The URL above retrieves information for 10 Downing Street, London, UK.

Parse the longitude and latitude information from Google for two post codes, in conjuntion with the Haversine Formula for a working solution:

using System;
using System.Net;
using System.Web;
using System.Xml;

namespace Codebrain
{
    public static class Distance
    {
        // Handy structure for Long/Lat information
        public struct Coords
        {
            public double Longitude;
            public double Latitude;
        }

        // Unit calculations
        public enum Units
        {
            Miles,
            Kilometres
        }

        // Will return a null if the Google API is unable to find either post code, or the country constraint fails
        public static double? BetweenTwoPostCodes(string postcodeA, string postcodeB, string countryCodeWithin, Units units)
        {
            var ll1 = PostCodeToLongLat(postcodeA, countryCodeWithin);
            if (!ll1.HasValue) return null;
            var ll2 = PostCodeToLongLat(postcodeB, countryCodeWithin);
            if (!ll2.HasValue) return null;
            return ll1.Value.DistanceTo(ll2.Value, units);
        }

        // Overload for UK post codes
        public static double? BetweenTwoUKPostCodes(string postcodeA, string postcodeB)
        {
            return BetweenTwoPostCodes(postcodeA, postcodeB, "GB", Units.Miles);
        }

        // Uses the Google API to resolve a post code (within the specified country)
        public static Coords? PostCodeToLongLat(string postcode, string countryCodeWithin)
        {
            // Download the XML response from Google
            var client = new WebClient();
            var encodedPostCode = HttpUtility.UrlEncode(postcode);
            var url = string.Format("http://maps.google.com/maps/geo?q={0}&output=xml", encodedPostCode);
            var xml = client.DownloadString(url);
            var doc = new XmlDocument();
            doc.LoadXml(xml);

            // Create a custom namespace manager
            var nsmgr = new XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("ge", "http://earth.google.com/kml/2.0");
            nsmgr.AddNamespace("oa", "urn:oasis:names:tc:ciq:xsdschema:xAL:2.0");

            // Any results?
            var nodelist = doc.SelectNodes("//ge:kml/ge:Response/ge:Placemark", nsmgr);
            if (nodelist == null || nodelist.Count == 0) return null;

            // Results are already ordered by accuracy, so take the first one
            var node = nodelist[0];

            // Check the Country constraint
            var countryname = node.SelectSingleNode("oa:AddressDetails/oa:Country/oa:CountryNameCode", nsmgr);
            if (countryname.FirstChild.Value != countryCodeWithin)
                return null;

            // Get the raw Long/Lat coordinates (I wish there was a nicer way..
            // perhaps averaging the LongLat enclosing box?)
            var coords = node.SelectSingleNode("ge:Point/ge:coordinates", nsmgr).FirstChild.Value.Split(',');
            double longitude;
            double lattitude;
            if (!Double.TryParse(coords[0], out longitude)) return null;
            if (!Double.TryParse(coords[1], out lattitude)) return null;

            return new Coords
                       {
                           Longitude = longitude,
                           Latitude = lattitude
                       };
        }

        public static double DistanceTo(this Coords from, Coords to, Units units)
        {
            // Haversine Formula...
            var dLat1InRad = from.Latitude * (Math.PI / 180.0);
            var dLong1InRad = from.Longitude * (Math.PI / 180.0);
            var dLat2InRad = to.Latitude * (Math.PI / 180.0);
            var dLong2InRad = to.Longitude * (Math.PI / 180.0);

            var dLongitude = dLong2InRad - dLong1InRad;
            var dLatitude = dLat2InRad - dLat1InRad;

            // Intermediate result a.
            var a = Math.Pow(Math.Sin(dLatitude / 2.0), 2.0) +
                    Math.Cos(dLat1InRad) * Math.Cos(dLat2InRad) *
                    Math.Pow(Math.Sin(dLongitude / 2.0), 2.0);

            // Intermediate result c (great circle distance in Radians).
            var c = 2.0 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1.0 - a));

            // Unit of measurement
            var radius = 6371;
            if (units == Units.Miles) radius = 3959;

            return radius * c;
        }
    }
}

Example Usage:

// The long way...
var distance = Distance.BetweenTwoPostCodes("BS1 6QQ", "SW1A 2AA", "GB", Distance.Units.Miles);
if (distance.HasValue) Console.WriteLine(distance.Value + " miles");
// ...or the short way
var distance = Distance.BetweenTwoUKPostCodes("BS1 6QQ", "SW1A 2AA");
if (distance.HasValue) Console.WriteLine(distance.Value + " miles");

It's not 100% accurate and technically speaking the distance is 'as the crow flies', but if you need simple information it'll do the trick nicely!

Tags: , , ,

Categories: .NET | C Sharp | Web

Asynchronous MVC Controllers + NServiceBus

07 May 2009 by Stuart Cam

NServiceBus is a powerful, yet lightweight, open source messaging framework for designing distributed .NET enterprise systems - just ask Udi Dahan the project founder. NServiceBus gives programmers a head-start on developing robust, scalable, and maintainable service-layers and long-running business processes.

I have personally used NServiceBus on projects and I really like what Udi has put together.

The ASP.NET MVC v1.0 Futures download adds functionality to MVC to enable asynchronous controller actions. The plumbing has already been blogged about by Maarten Balliauw, so I won't repeat it. Maarten has written some sample code to demonstrate the various patterns available (Maarten, your IndexDelegate controller action needs some work!).

I thought it would be interesting to use the MVC futures library in conjuntion with NServiceBus.

The NServiceBus Full Source Download contains an Async Web Forms sample which includes a Server + Web Site. I have simply created an MVC site to interact with the Server.

The main changes to Maarten's code have been in the HomeController.cs file:

using System;
using System.Web.Mvc;
using Microsoft.Web.Mvc;
using System.Threading;
using Messages;
using NServiceBus;

namespace MvcAsyncControllersExample.Controllers
{
    [HandleError]
    public class HomeController : AsyncController
    {
        public ActionResult Index()
        {
            return View();
        }

        private int GetCommandId()
        {
            int value;
            var success = Int32.TryParse(Request.Form["Value"], out value);
            return success ? value : 0;
        }

        // IAsync Method
        public IAsyncResult BeginIndexIAsync(AsyncCallback callback, object state)
        {
            var command = new Command { Id = GetCommandId() };
            return MvcApplication.Bus.Send(command).Register(callback, state);
        }

        public ActionResult EndIndexIAsync(IAsyncResult ar)
        {
            var result = ar.AsyncState as CompletionResult;
            ViewData["Result"] = (result == null) ? "null" : Enum.GetName(typeof(ErrorCodes), result.ErrorCode);
            ViewData["Date"] = DateTime.Now.ToString();
            return View("Index");
        }

        // Event Method (This techniques is designed to 'wrap' a synchronous call with
        //               some plumbing, whereas NServiceBus is asynchronous by design,
        //               so in this instance it seems cumbersome)
        public void IndexEvent()
        {
            AsyncManager.OutstandingOperations.Increment();
            ThreadPool.QueueUserWorkItem(o =>
            {
                var result = new CompletionResult();
                var command = new Command { Id = GetCommandId() };

                var sync = MvcApplication.Bus.Send(command).Register(asyncResult =>
                                                                     {
                                                                         result = asyncResult.AsyncState as CompletionResult;
                                                                     },
                                                                     null);
                sync.AsyncWaitHandle.WaitOne();

                var resultString = (result == null) ? "null" : Enum.GetName(typeof(ErrorCodes), result.ErrorCode);
                AsyncManager.Parameters.Add("Result", resultString);
                AsyncManager.OutstandingOperations.Decrement();

            }, null);
        }

        public ActionResult IndexEventCompleted()
        {
            ViewData["Result"] = AsyncManager.Parameters["Result"];
            ViewData["Date"] = DateTime.Now.ToString();
            return View("Index");
        }

        // Delegate Method
        public Func<ActionResult> IndexDelegate()
        {
            AsyncManager.RegisterTask(callback =>
                                      {
                                          var command = new Command { Id = GetCommandId() };
                                          return MvcApplication.Bus.Send(command).Register(callback, null);
                                      },
                                      ar =>
                                      {
                                          var result = ar.AsyncState as CompletionResult;
                                          ViewData["Result"] = (result == null) ? "null" : Enum.GetName(typeof(ErrorCodes), result.ErrorCode);
                                          ViewData["Date"] = DateTime.Now.ToString();
                                      });
            return () => View("Index");
        }
    }
}

Along with some additional plumbing in the Global.asax.cs:

using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Web.Mvc;
using NServiceBus;

namespace MvcAsyncControllersExample
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static IBus Bus { get; private set; }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapAsyncRoute(
                "Default",                                              // Route name
                "{controller}/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
            );
        }

        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);

            Bus = Configure.WithWeb()
                           .SpringBuilder()
                           .XmlSerializer()
                           .MsmqTransport()
                               .IsTransactional(false)
                               .PurgeOnStartup(false)
                           .UnicastBus()
                               .ImpersonateSender(false)
                           .CreateBus()
                           .Start();
        }
    }
}

MVC web site in action

Asynchronous MVC Controller & NServiceBus sample site

Download the sample code here: MvcAsyncControllersExample_NServiceBus.zip (676.51 kb)

Tags: , , ,

Categories: C Sharp | MVC | SOA


© Codebrain 2017. All Rights Reserved. Registered in England: 07744920. VAT: GB 119 4078 13