Pages

Wednesday, 28 April 2010

Silverlight for Business

Now, I'm not normally one to push other folks' products but here I'll make an exception. We are currently looking at introducing Silverlight 4 into our line-of-business applications and, so, this topic is forefront in my mind. I would like to see more blogs, podcasts, examples, labs and training courses targeting business applications rather than the usual "lets wrap an HD video around a sphere and then rotating it". So...

The Silverlight Tour comes to the UK – and it’s called the Masterclass!

This 3 day hands-on training with both designer and developer tracks looks awesome and (uniquely) has two expert trainers per course.

Currently scheduled in London, Manchester, and the Midlands for June, all courses also come with the chance to win an xbox 360, and Silverlight Spy licences!

Early bird discount of £100 if you book in May, and if you are a member of #SLUGUK or #nxtgenug there are additional discounts to be had.

Full Details are here: http://silverlightmasterclass.net

In addition bbits are holding a raffle for a free ticket for the masterclass. To be eligible to win the ticket (worth £1095!) you MUST paste this text, including all links, into your blog and email Ian@bbits.co.uk with the url to the blog entry. The draw will be made on June 1st and the winner informed by email and on http://silverlightmasterclass.net

Tuesday, 20 April 2010

Enhancing the Aggregate Pattern in Domain Driven Design with Weak References

Note: This post makes use of the generic WeakReference class illustrated in this post.

I'm working my way through Eric Evan's wonderful book Domain Driven Design and, already, it has a place on my "books-every-developer-should-read" shelf. One of the 3 main design patterns covered in chapter 6 is Aggregate. One of the tenets of this pattern is that external objects can request a reference to an internal object of the Aggregate on the assumption that they use it fleetingly and do not hold a permanent reference to it. The reason for this is that the Aggregate needs to be disposable as a whole and this will not happen if some internal objects are still being referenced.

Now, the problem with this is that, certainly in .Net, there is nothing in the language to enforce this requirement. As a developer you have to write your Aggregates and hope that the next developer to consume them understands the pattern requirements. A simple recipe for disaster!

Enter the genreric WeakReference class.

I'll extend Eric's example using his idea of a Car class (omitting any Factory or Repository complications)...

public enum WheelLocation
{
  FrontLeft,
  FrontRight,
  RearLeft,
  RearRight
}

public class Wheel : IDisposable
{
  public WheelLocation Location
  {
    get;
    private set;
  }
   
  public Wheel(WheelLocation location)
  {
    Location = location;
  }

  public void Dispose()
  {
  }
}

public class Car : IDisposable
{
  public Guid ID
  {
    get;
    private set;
  }

  private IList<Wheel> _wheels;

  public Car(Guid id)
  {
    ID = id;

    _wheels = new List<Wheel>(4);

    _wheels.Add(new Wheel(WheelLocation.FrontLeft));
    _wheels.Add(new Wheel(WheelLocation.FrontRight));
    _wheels.Add(new Wheel(WheelLocation.RearLeft));
    _wheels.Add(new Wheel(WheelLocation.RearRight));
  }

  public void Dispose()
  {
    foreach (IDisposable obj in _wheels)
      obj.Dispose();
  }

  public Wheel GetWheel(WheelLocation location)
  {
    return _wheels.Where(w => w.Location == location).Single();
  }
}

So, we now have a nicely encapsulated Car Aggregate class that can also, indirectly, supply any consumers with references to its internal objects (Wheels). Here's a (kinda dumb!) usage example...

public class WheelEventArgs : EventArgs
{
  public Wheel Wheel { get; private set; }

  public CarEventArgs(Wheel wheel)
    : base()
  {
    Wheel = wheel;
  }
}

public class CarConsumer
{
  public void CreateCar(Guid id)
  {
    using (var car = new Car(id))
    {
      OnCarCreate(car);
    }
  }

  protected virtual void OnCarCreated(Car car)
  {
    if (CarCreated != null)
    {
      CarCreated(this, new EventArgs(car.GetWheel(WheelLocation.FrontLeft));
      CarCreated(this, new EventArgs(car.GetWheel(WheelLocation.FrontRight));
      CarCreated(this, new EventArgs(car.GetWheel(WheelLocation.RearLeft));
      CarCreated(this, new EventArgs(car.GetWheel(WheelLocation.RearRight));
    }
  }

  public event CarCreated;
}

The problem here is that we have no way of knowing whether the classes that registered to the CarCreated event still have references to the Wheel objects when we come to dispose our Car class.

So, what we can do is change the GetWheel method to return weak references to the internal wheels...

public WeakReference<Wheel> GetWheel(WheelLocation location)
{
  return new WeakReference<Wheel>(_wheels.Where(w => w.Location == location).Single());
}

Now, this doesn't prevent the external objects from securing a strong reference to the wheels and it doesn't stop dumb developers doing dumb things; but it does indicate our intention with the pattern. "Hey, look, I'm returning a WeakReference to this object - there's a reason for it!"

Generic WeakReference Class

The WeakReference class is used to get a reference to an object X in such a way that the garbage collector (GC) can still reclaim it. Holding a 'normal', strong reference to object X would stop the GC from collecting it.

The .Net BCL currently only contains a non-generic class for this functionality, so I wrote a simple generic version...

namespace System
{
  public class WeakReference<T> : WeakReference
  {
    public new T Object
    {
      get
      {
        return (T)base.Target;
      }
      set
      {
        base.Target = value;
      }
    }
    public WeakReference(T target)
      : base(target)
    {
    }
    public WeakReference(T target, bool trackResurrection)
      : base(target, trackResurrection)
    {
    }
    protected WeakReference(SerializationInfo info, StreamingContext context)
      : base(info, context)
    {
    }
  }
}

And here's how you can use it...

public class Dog : IDisposable
{
  public string Name
  {
    get;
    private set;
  }

  public Dog(string name)
  {
    Name = name;
  }

  // IDisposable routines left out for brevity
}

public class Consumer
{
  public void DoSomething()
  {
    using (var myDog = new Dog("Dioji"))
    {
      var weakReference = new WeakReference<Dog>(myDog);

      Console.WriteLine("My dog is called '{0}'.", weakReference.Object.Name);
    }
  }
}

I'll demonstrate why this can be really useful in my next post on the "Enhancing the Aggregate Pattern in Domain Driven Design with Weak References".

Thursday, 15 April 2010

Problems sending Email through IIS7 (SmtpFailedRecipientException)

Moved some of our applications to a new web server (Windows Server 2008 R2 + IIS7) and now the email notifications don't work. Well, that's not entirely true because they work for all mail going to any address on our company's domain, but not to anyone else. Extremely irritating because I'm a developer, not a network specialist but, in a small company you have to wear many hats.

First, just because you have the SMTP Email feature enabled in IIS7 doesn't mean you can actually send mail. You still have to have an Smtp Virtual Server set up. You do this via the "IIS 6.0 Manager" link. Thankfully, that's not the confusing bit!

I'm rambling and, anyway, all the information above is easily discoverable online.

So, every time my ASP.Net application attempted to send an email to an external address (e.g. someone@gmail.com) the system would throw a System.Net.Mail.SmtpFailedRecipientException "Mailbox unavailable. The server response was: 5.7.1. Unable to relay for someone@gmail.com".

Here's how I fixed it...

1. In IIS 6.0 Manager right click on the SMTP virtual server and choose properties.
2. In the Access tab click the Relay button.
3. "Only the list below" and "Allow all computers which successfully..." should both be selected.
4. I thought this would be enough, but it wasn't.
5. You also have to add the IP address(es) of your server to the list (e.g. 127.0.0.1).

Et voila!

Now, as I said before, I'm not a network specialist so this is almost certainly not the 'suggested' solution; but, hey, it worked for us.

Wednesday, 14 April 2010

Goodbye x64, Hello x86

I wrote a little rant back in February 2009 about my annoyance at unmanaged code. I have now made the decision to drop back down to an x86 architecture as I upgrade to Windows 7.

Whilst it's certainly quite 'cool' to say that I run a 64 bit development machine do I really need it? For servers it's a definite 'yes' - mainly for the > 4GB memory space; but for the rest of us, probably 'no'.

I don't use more than 4GB RAM and, whilst the x64 architecture is slightly better / newer / maturer than the equivalent in x86 it doesn't make a bit of difference. You might even notice a reduction in performance due to the larger memory space pointers!

Visual Studio 2010 shipped yesterday - 32 bit only. A lot of software vendors are still wedded to unmanaged code - normally 32 bit only. Even IE8 64bit seems to have issues on my machine.

My biggest driver, though, is our company VPN. The client software will not work on Windows 7 x64. We can get an upgrade, but it's gonna cost us #fail.

So, until x64 becomes mainstream and not something that I either have to wait for or pay extra for I'm back down to 32 little bits.

Tuesday, 6 April 2010

Adding a Lazy Loading Pattern to T4MVC

I added T4MVC to our ASP.NET MVC application yesterday. Great idea - don't know why it's taken me so long to get 'round to it? Unfortunately, a number of my unit tests were now failing with a System.NotImplementedException being thrown.

Some of our controllers are currently redundant so I changed the base class' constructor to make sure no-one called them accidentally...

public abstract class MyRedundantBaseClass
  {
    public MyRedundantBaseClass()
    {
      throw new NotImplementedException();
    }
  }

Now, none of my tests go anywhere near this class (or any inherited ones) so why was it throwing the exceptions?

The problem is in one of the auto-generated classes in the T4MVC.cs file. The template generates a static field for each non-abstract controllers in your application...

public static class MVC
  {
    public static MyApp.Controllers.Account.AccountController Account = new MyApp.Controllers.Account.T4MVC_AccountController();
    // Repeated for each controller...
  }

This list of fields also included a number that extended my redundant class. So, as soon as I did anything with the T4MVC framework all these classes got automatically instantiated and now I'm dead in the water.

My solution is to edit the template so that it generates a Lazy Loading version of the T4MVC.cs file. This also makes it a little more efficient as it will only new-up classes when it needs them.

Here's the old template section (starting from line 73)...

<#foreach (var controller in DefaultArea.GetControllers()) { #>
    public static <#=controller.FullClassName #> <#=controller.Name #> = new <#=controller.FullDerivedClassName #>();
<#} #>

... and here's what I changed it to...

<#foreach (var controller in DefaultArea.GetControllers()) { #>
 private static <#=controller.FullClassName #> _<#=controller.Name #>;
<#} #>
<#foreach (var controller in DefaultArea.GetControllers()) { #>
 public static <#=controller.FullClassName #> <#=controller.Name #>
 {
  get
  {
   if (_<#=controller.Name #> == null)
    _<#=controller.Name #> = new <#=controller.FullDerivedClassName #>();
    
   return _<#=controller.Name #>;
  }
 }
<#} #>

This now generates the following code in T4MVC.cs...

public static class MVC
  {
    private static MyApp.Controllers.Account.AccountController _Account;

    public static MyApp.Controllers.Account.AccountController Account
    {
      get
      {
        if (_Account == null)
          _Account = new MyApp.Controllers.Account.T4MVC_AccountController();

        return _Account;
      }
    }

    // Repeated for each controller...
  }

I still need to add a double locking mechanism for thread safety, but I think this makes a valuable improvement to an already great framework.