<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Jeroen's Blog - Programming</title>
    <link>http://www.jeroenlandheer.com/Blog/</link>
    <description>A Dutch software developer living in Chile</description>
    <language>en-us</language>
    <copyright>Jeroen Landheer</copyright>
    <lastBuildDate>Mon, 27 Jul 2009 19:02:34 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>jeroen@landheer.com</managingEditor>
    <webMaster>jeroen@landheer.com</webMaster>
    <item>
      <trackback:ping>http://www.jeroenlandheer.com/Blog/Trackback.aspx?guid=54a5d7d9-08d6-41fb-9f14-1e5093de136e</trackback:ping>
      <pingback:server>http://www.jeroenlandheer.com/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.jeroenlandheer.com/Blog/PermaLink,guid,54a5d7d9-08d6-41fb-9f14-1e5093de136e.aspx</pingback:target>
      <dc:creator>Jeroen Landheer</dc:creator>
      <wfw:comment>http://www.jeroenlandheer.com/Blog/CommentView,guid,54a5d7d9-08d6-41fb-9f14-1e5093de136e.aspx</wfw:comment>
      <wfw:commentRss>http://www.jeroenlandheer.com/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=54a5d7d9-08d6-41fb-9f14-1e5093de136e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
During some testing, I needed a tool that could simply compress a file to GZip format
and back again. I decided that other people might have a similar need, so here’s the
code to make it work.
</p>
        <pre class="brush: csharp;">using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Compression;
using System.IO;

namespace GZip
{
  class Program
  {
    static void Main(string[] args)
    {
      CompressionMode mode = CompressionMode.Compress;

      if (args.Length != 3)
      {
        ShowUsage();
        return;
      }

      string command = args[0].ToLower();
      switch (command)
      {
        case "compress":
          mode = CompressionMode.Compress;
          break;
        case "decompress":
          mode = CompressionMode.Decompress;
          break;
        default:
          ShowUsage();
          return;
      }

      Stream sourceStream = File.OpenRead(args[1]);
      Stream targetStream = File.OpenWrite(args[2]);

      switch (mode)
      {
        case CompressionMode.Compress:
          using (GZipStream gZip = new GZipStream(targetStream, CompressionMode.Compress))
          {
            Pump(sourceStream, gZip);
          }

          break;
        case CompressionMode.Decompress:
          using (GZipStream gZip = new GZipStream(sourceStream, CompressionMode.Decompress))
          {
            Pump(gZip, targetStream);
          }
          break;
      }
      sourceStream.Close();
      targetStream.Close();

    }

    private static void Pump(Stream source, Stream target)
    {
      byte[] buffer = new byte[65536];
      int count;
      while ((count = source.Read(buffer, 0, buffer.Length)) &gt; 0)
      {
        target.Write(buffer, 0, count);
      }

    }

    private static void ShowUsage()
    {
      Console.WriteLine("Usage: GZip compress | decompress   sourceFileName targetFileName");
    }
  }
}

</pre>
        <img width="0" height="0" src="http://www.jeroenlandheer.com/Blog/aggbug.ashx?id=54a5d7d9-08d6-41fb-9f14-1e5093de136e" />
        <br />
        <hr />
This website is sposored by <a href="http://www.thewheel.nl">The Wheel Automatisering</a>.</body>
      <title>A very simple GZip command line tool</title>
      <guid isPermaLink="false">http://www.jeroenlandheer.com/Blog/PermaLink,guid,54a5d7d9-08d6-41fb-9f14-1e5093de136e.aspx</guid>
      <link>http://www.jeroenlandheer.com/Blog/2009/07/27/AVerySimpleGZipCommandLineTool.aspx</link>
      <pubDate>Mon, 27 Jul 2009 19:02:34 GMT</pubDate>
      <description>&lt;p&gt;
During some testing, I needed a tool that could simply compress a file to GZip format
and back again. I decided that other people might have a similar need, so here’s the
code to make it work.
&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Compression;
using System.IO;

namespace GZip
{
  class Program
  {
    static void Main(string[] args)
    {
      CompressionMode mode = CompressionMode.Compress;

      if (args.Length != 3)
      {
        ShowUsage();
        return;
      }

      string command = args[0].ToLower();
      switch (command)
      {
        case "compress":
          mode = CompressionMode.Compress;
          break;
        case "decompress":
          mode = CompressionMode.Decompress;
          break;
        default:
          ShowUsage();
          return;
      }

      Stream sourceStream = File.OpenRead(args[1]);
      Stream targetStream = File.OpenWrite(args[2]);

      switch (mode)
      {
        case CompressionMode.Compress:
          using (GZipStream gZip = new GZipStream(targetStream, CompressionMode.Compress))
          {
            Pump(sourceStream, gZip);
          }

          break;
        case CompressionMode.Decompress:
          using (GZipStream gZip = new GZipStream(sourceStream, CompressionMode.Decompress))
          {
            Pump(gZip, targetStream);
          }
          break;
      }
      sourceStream.Close();
      targetStream.Close();

    }

    private static void Pump(Stream source, Stream target)
    {
      byte[] buffer = new byte[65536];
      int count;
      while ((count = source.Read(buffer, 0, buffer.Length)) &amp;gt; 0)
      {
        target.Write(buffer, 0, count);
      }

    }

    private static void ShowUsage()
    {
      Console.WriteLine("Usage: GZip compress | decompress   sourceFileName targetFileName");
    }
  }
}

&lt;/pre&gt;&lt;img width="0" height="0" src="http://www.jeroenlandheer.com/Blog/aggbug.ashx?id=54a5d7d9-08d6-41fb-9f14-1e5093de136e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
This website is sposored by &lt;a href="http://www.thewheel.nl"&gt;The Wheel Automatisering&lt;/a&gt;.</description>
      <comments>http://www.jeroenlandheer.com/Blog/CommentView,guid,54a5d7d9-08d6-41fb-9f14-1e5093de136e.aspx</comments>
      <category>Programming</category>
    </item>
    <item>
      <trackback:ping>http://www.jeroenlandheer.com/Blog/Trackback.aspx?guid=b7cefdec-3f9c-4330-b787-66945b581c77</trackback:ping>
      <pingback:server>http://www.jeroenlandheer.com/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.jeroenlandheer.com/Blog/PermaLink,guid,b7cefdec-3f9c-4330-b787-66945b581c77.aspx</pingback:target>
      <dc:creator>Jeroen Landheer</dc:creator>
      <wfw:comment>http://www.jeroenlandheer.com/Blog/CommentView,guid,b7cefdec-3f9c-4330-b787-66945b581c77.aspx</wfw:comment>
      <wfw:commentRss>http://www.jeroenlandheer.com/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=b7cefdec-3f9c-4330-b787-66945b581c77</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It’s always fun to play with .Net, the HTTP Listener class in .Net 2.0 makes it really
easy. With this little block of code you can setup a very simple (multithreaded) web
server…
</p>
        <pre class="brush: csharp;">private static System.Threading.AutoResetEvent listenForNextRequest = new System.Threading.AutoResetEvent(false);

protected Server() 
{
  _httpListener = new HttpListener();
}

private HttpListener _httpListener;

public string Prefix { get; set; }
public void Start()
{
  if (String.IsNullOrEmpty(Prefix))
    throw new InvalidOperationException("No prefix has been specified");
  _httpListener.Prefixes.Clear();
  _httpListener.Prefixes.Add(Prefix);
  _httpListener.Start();
  System.Threading.ThreadPool.QueueUserWorkItem(Listen);

}

internal void Stop()
{
  _httpListener.Stop();
  IsRunning = false;
}

public bool IsRunning { get; private set; }

private void ListenerCallback(IAsyncResult result)
{
  HttpListener listener = result.AsyncState as HttpListener;
  HttpListenerContext context = null;

  if (listener == null)
    // Nevermind
    return;

  try
  {
    context = listener.EndGetContext(result);
  }
  catch (Exception ex)
  {
    System.Diagnostics.Debug.WriteLine(ex.ToString());
    return;
  }
  finally
  {
    listenForNextRequest.Set();
  }
  if (context == null)
    return;
  ProcessRequest(context);
}

// Loop here to begin processing of new requests.
private void Listen(object state)
{
  while (_httpListener.IsListening)
  {
    _httpListener.BeginGetContext(new AsyncCallback(ListenerCallback), _httpListener);
    listenForNextRequest.WaitOne();
  }
}

protected abstract void ProcessRequest(HttpListenerContext context);

</pre>
        <p>
Always nice to have ;)
</p>
        <img width="0" height="0" src="http://www.jeroenlandheer.com/Blog/aggbug.ashx?id=b7cefdec-3f9c-4330-b787-66945b581c77" />
        <br />
        <hr />
This website is sposored by <a href="http://www.thewheel.nl">The Wheel Automatisering</a>.</body>
      <title>World’s smallest web server</title>
      <guid isPermaLink="false">http://www.jeroenlandheer.com/Blog/PermaLink,guid,b7cefdec-3f9c-4330-b787-66945b581c77.aspx</guid>
      <link>http://www.jeroenlandheer.com/Blog/2009/07/27/WorldsSmallestWebServer.aspx</link>
      <pubDate>Mon, 27 Jul 2009 17:21:45 GMT</pubDate>
      <description>&lt;p&gt;
It’s always fun to play with .Net, the HTTP Listener class in .Net 2.0 makes it really
easy. With this little block of code you can setup a very simple (multithreaded) web
server…
&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;private static System.Threading.AutoResetEvent listenForNextRequest = new System.Threading.AutoResetEvent(false);

protected Server() 
{
  _httpListener = new HttpListener();
}

private HttpListener _httpListener;

public string Prefix { get; set; }
public void Start()
{
  if (String.IsNullOrEmpty(Prefix))
    throw new InvalidOperationException("No prefix has been specified");
  _httpListener.Prefixes.Clear();
  _httpListener.Prefixes.Add(Prefix);
  _httpListener.Start();
  System.Threading.ThreadPool.QueueUserWorkItem(Listen);

}

internal void Stop()
{
  _httpListener.Stop();
  IsRunning = false;
}

public bool IsRunning { get; private set; }

private void ListenerCallback(IAsyncResult result)
{
  HttpListener listener = result.AsyncState as HttpListener;
  HttpListenerContext context = null;

  if (listener == null)
    // Nevermind
    return;

  try
  {
    context = listener.EndGetContext(result);
  }
  catch (Exception ex)
  {
    System.Diagnostics.Debug.WriteLine(ex.ToString());
    return;
  }
  finally
  {
    listenForNextRequest.Set();
  }
  if (context == null)
    return;
  ProcessRequest(context);
}

// Loop here to begin processing of new requests.
private void Listen(object state)
{
  while (_httpListener.IsListening)
  {
    _httpListener.BeginGetContext(new AsyncCallback(ListenerCallback), _httpListener);
    listenForNextRequest.WaitOne();
  }
}

protected abstract void ProcessRequest(HttpListenerContext context);

&lt;/pre&gt;
&lt;p&gt;
Always nice to have ;)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.jeroenlandheer.com/Blog/aggbug.ashx?id=b7cefdec-3f9c-4330-b787-66945b581c77" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
This website is sposored by &lt;a href="http://www.thewheel.nl"&gt;The Wheel Automatisering&lt;/a&gt;.</description>
      <comments>http://www.jeroenlandheer.com/Blog/CommentView,guid,b7cefdec-3f9c-4330-b787-66945b581c77.aspx</comments>
      <category>Programming</category>
    </item>
    <item>
      <trackback:ping>http://www.jeroenlandheer.com/Blog/Trackback.aspx?guid=d7c03e9c-f1a8-4bd4-b49d-f9f86c49313e</trackback:ping>
      <pingback:server>http://www.jeroenlandheer.com/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.jeroenlandheer.com/Blog/PermaLink,guid,d7c03e9c-f1a8-4bd4-b49d-f9f86c49313e.aspx</pingback:target>
      <dc:creator>Jeroen Landheer</dc:creator>
      <wfw:comment>http://www.jeroenlandheer.com/Blog/CommentView,guid,d7c03e9c-f1a8-4bd4-b49d-f9f86c49313e.aspx</wfw:comment>
      <wfw:commentRss>http://www.jeroenlandheer.com/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=d7c03e9c-f1a8-4bd4-b49d-f9f86c49313e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Let’s say you would like to be able to extend your application with C# scripting abilities.
You can do this by simply compiling the script and running it. The problem is that
these kind of scripts take up memory that isn’t going to be released any time soon.
Another problem is that the script can do anything your program can… or when an exception
is thrown, your program crashes… is that really the idea? 
</p>
        <p>
Enter the use of application domains. Application domains are just for doing these
kind of things. Loading temporary assemblies, executing partially trusted code and
do memory-intensive work so you don’t need to GC.Collect at the end of the day. (Normally
we wouldn’t want to interfere with .Net memory management, because there wouldn’t
be much reason to. .Net does a very good job all by itself!) 
</p>
        <p>
Let’s start with a very simple example:
</p>
        <pre class="brush: csharp;">using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace MyAppDomain
{
  class Program
  {
    static void Main(string[] args)
    {
      Worker localWorker = new Worker();
      Console.WriteLine("localWorker is running in: {0}", localWorker.DomainName);
      AppDomain myDomain = null;
      try
      {
        myDomain = AppDomain.CreateDomain("Remote Domain");
        Worker remoteWorker = (Worker)myDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, "MyAppDomain.Worker");
        Console.WriteLine("remoteWorker is running in: {0}", remoteWorker.DomainName);
      }
      finally
      {
        if (myDomain != null) 
          AppDomain.Unload(myDomain);
      }

    }
  }

  public class Worker : MarshalByRefObject
  {
    public Worker()
    {

    }

    public string DomainName
    {
      get
      {
        return AppDomain.CurrentDomain.FriendlyName;
      }
    }

  }
}

</pre>
        <p>
What you see here is:
</p>
        <ul>
          <li>
An application domain is created</li>
          <li>
A value is sent from the new application domain back to the local domain.</li>
          <li>
We have a strongly-typed reference to the remote object</li>
        </ul>
        <p>
In this example, the remote domain is running with the same privileges as the local
domain. 
</p>
        <p>
          <strong>Let’s crash…</strong>
        </p>
        <p>
Unhandled exceptions can cause code to crash or leave your application in an unstable
state. AppDomains are isolated and can help you to catch unhandled exceptions and
unload the application domain when needed. So when we expand our example to include
this, we get something like this:
</p>
        <pre class="brush: csharp;">using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace MyAppDomain
{
  class Program
  {
    static void Main(string[] args)
    {
      AppDomain myDomain = null;
      try
      {
        myDomain = AppDomain.CreateDomain("Remote Domain");
        myDomain.UnhandledException += new UnhandledExceptionEventHandler(myDomain_UnhandledException);
        Worker remoteWorker = (Worker)myDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Worker).FullName);
        remoteWorker.VeryBadMethod();
      }
      catch(Exception ex)
      {
        myDomain_UnhandledException(myDomain, new UnhandledExceptionEventArgs(ex, false));
      }
      finally
      {
        if (myDomain != null)
          AppDomain.Unload(myDomain);
      }

      Console.ReadLine();
    }

    static void myDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
      Exception ex = e.ExceptionObject as Exception;
      if (ex != null)
        Console.WriteLine(ex.Message);
      else
        Console.WriteLine("A unknown exception was thrown");
    }
  }

  public class Worker : MarshalByRefObject
  {
    public Worker()
    {

    }

    public string DomainName
    {
      get
      {
        return AppDomain.CurrentDomain.FriendlyName;
      }
    }

    public void VeryBadMethod()
    {
      // Autch!
      throw new InvalidOperationException();
    }

  }
}

</pre>
        <p>
          <strong>Loading assemblies in the remote application domain</strong>
        </p>
        <p>
When loading an assembly in the remote domain, the assembly gets unloaded once the
application domain gets unloaded. So if Worker would load an assembly, this would
not be a problem as long as worker is in a separate domain. Here’s another example.
</p>
        <p>
First, we create a simply plugin assembly:
</p>
        <pre class="brush: csharp;">using System;
using System.Collections.Generic;
using System.Text;

namespace MyPluginAssembly
{
  public class MyPlugin
  {
    public MyPlugin()
    {

    }

    public string Hello()
    {
      return "Hello";
    }
  }
}

</pre>
        <p>
This assembly needs to be compiled and for the sake of simplicity we’ll call it “MyPluginAssembly.dll”.
Copy this dll to the same directory as the MyAppDomain output folder. Next, we’ll
change the example a bit and load the assembly, do some reflection, run the Hello
method and print the result.
</p>
        <pre class="brush: csharp;">using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace MyAppDomain
{
  class Program
  {
    static void Main(string[] args)
    {
      AppDomain myDomain = null;
      try
      {
        myDomain = AppDomain.CreateDomain("Remote Domain");
        myDomain.UnhandledException += new UnhandledExceptionEventHandler(myDomain_UnhandledException);
        Worker remoteWorker = (Worker)myDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Worker).FullName);

        Console.WriteLine(remoteWorker.RunPlugin());

        PrintAssemblies(myDomain);
        PrintAssemblies(AppDomain.CurrentDomain);

      }
      catch(Exception ex)
      {
        myDomain_UnhandledException(myDomain, new UnhandledExceptionEventArgs(ex, false));
      }
      finally
      {
        if (myDomain != null)
        {
          Console.ForegroundColor = ConsoleColor.Red;
          Console.WriteLine("Unloading {0}", myDomain.FriendlyName);
          Console.ForegroundColor = ConsoleColor.Gray;
          AppDomain.Unload(myDomain);
        }
      }

      PrintAssemblies(AppDomain.CurrentDomain);


      Console.ReadLine();
    }

    static void myDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
      Exception ex = e.ExceptionObject as Exception;
      if (ex != null)
        Console.WriteLine(ex.Message);
      else
        Console.WriteLine("A unknown exception was thrown");
    }

    static void PrintAssemblies(AppDomain domain)
    {
      Console.ForegroundColor = ConsoleColor.Yellow;
      Console.WriteLine("Assemblies loaded in domain {0} are:", domain.FriendlyName);
      Console.ForegroundColor = ConsoleColor.Gray;
      foreach (var item in domain.GetAssemblies())
      {
        Console.WriteLine(item.FullName);
      }
    }
  }



  public class Worker : MarshalByRefObject
  {
    public Worker()
    {

    }

    public string DomainName
    {
      get
      {
        return AppDomain.CurrentDomain.FriendlyName;
      }
    }

    public string RunPlugin()
    {
      Assembly asm = Assembly.LoadFrom("MyPluginAssembly.dll");
      Type pluginType = asm.GetType("MyPluginAssembly.MyPlugin");
      object plugin = pluginType.GetConstructor(new Type[0]).Invoke(new object[0]);
      return (string)pluginType.GetMethod("Hello").Invoke(plugin, new object[0]);
    }

  }
}

</pre>What
you’ll notice is that the first list will show that the remote’s plugin assembly is
also loaded in the local appdomain. But once the AppDomain is unloaded, the plugin
assembly is gone. <img width="0" height="0" src="http://www.jeroenlandheer.com/Blog/aggbug.ashx?id=d7c03e9c-f1a8-4bd4-b49d-f9f86c49313e" /><br /><hr />
This website is sposored by <a href="http://www.thewheel.nl">The Wheel Automatisering</a>.</body>
      <title>Running code in a different AppDomain</title>
      <guid isPermaLink="false">http://www.jeroenlandheer.com/Blog/PermaLink,guid,d7c03e9c-f1a8-4bd4-b49d-f9f86c49313e.aspx</guid>
      <link>http://www.jeroenlandheer.com/Blog/2009/06/07/RunningCodeInADifferentAppDomain.aspx</link>
      <pubDate>Sun, 07 Jun 2009 16:43:50 GMT</pubDate>
      <description>&lt;p&gt;
Let’s say you would like to be able to extend your application with C# scripting abilities.
You can do this by simply compiling the script and running it. The problem is that
these kind of scripts take up memory that isn’t going to be released any time soon.
Another problem is that the script can do anything your program can… or when an exception
is thrown, your program crashes… is that really the idea? 
&lt;/p&gt;
&lt;p&gt;
Enter the use of application domains. Application domains are just for doing these
kind of things. Loading temporary assemblies, executing partially trusted code and
do memory-intensive work so you don’t need to GC.Collect at the end of the day. (Normally
we wouldn’t want to interfere with .Net memory management, because there wouldn’t
be much reason to. .Net does a very good job all by itself!) 
&lt;/p&gt;
&lt;p&gt;
Let’s start with a very simple example:
&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace MyAppDomain
{
  class Program
  {
    static void Main(string[] args)
    {
      Worker localWorker = new Worker();
      Console.WriteLine("localWorker is running in: {0}", localWorker.DomainName);
      AppDomain myDomain = null;
      try
      {
        myDomain = AppDomain.CreateDomain("Remote Domain");
        Worker remoteWorker = (Worker)myDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, "MyAppDomain.Worker");
        Console.WriteLine("remoteWorker is running in: {0}", remoteWorker.DomainName);
      }
      finally
      {
        if (myDomain != null) 
          AppDomain.Unload(myDomain);
      }

    }
  }

  public class Worker : MarshalByRefObject
  {
    public Worker()
    {

    }

    public string DomainName
    {
      get
      {
        return AppDomain.CurrentDomain.FriendlyName;
      }
    }

  }
}

&lt;/pre&gt;
&lt;p&gt;
What you see here is:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
An application domain is created&lt;/li&gt;
&lt;li&gt;
A value is sent from the new application domain back to the local domain.&lt;/li&gt;
&lt;li&gt;
We have a strongly-typed reference to the remote object&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
In this example, the remote domain is running with the same privileges as the local
domain. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Let’s crash…&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Unhandled exceptions can cause code to crash or leave your application in an unstable
state. AppDomains are isolated and can help you to catch unhandled exceptions and
unload the application domain when needed. So when we expand our example to include
this, we get something like this:
&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace MyAppDomain
{
  class Program
  {
    static void Main(string[] args)
    {
      AppDomain myDomain = null;
      try
      {
        myDomain = AppDomain.CreateDomain("Remote Domain");
        myDomain.UnhandledException += new UnhandledExceptionEventHandler(myDomain_UnhandledException);
        Worker remoteWorker = (Worker)myDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Worker).FullName);
        remoteWorker.VeryBadMethod();
      }
      catch(Exception ex)
      {
        myDomain_UnhandledException(myDomain, new UnhandledExceptionEventArgs(ex, false));
      }
      finally
      {
        if (myDomain != null)
          AppDomain.Unload(myDomain);
      }

      Console.ReadLine();
    }

    static void myDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
      Exception ex = e.ExceptionObject as Exception;
      if (ex != null)
        Console.WriteLine(ex.Message);
      else
        Console.WriteLine("A unknown exception was thrown");
    }
  }

  public class Worker : MarshalByRefObject
  {
    public Worker()
    {

    }

    public string DomainName
    {
      get
      {
        return AppDomain.CurrentDomain.FriendlyName;
      }
    }

    public void VeryBadMethod()
    {
      // Autch!
      throw new InvalidOperationException();
    }

  }
}

&lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;Loading assemblies in the remote application domain&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
When loading an assembly in the remote domain, the assembly gets unloaded once the
application domain gets unloaded. So if Worker would load an assembly, this would
not be a problem as long as worker is in a separate domain. Here’s another example.
&lt;/p&gt;
&lt;p&gt;
First, we create a simply plugin assembly:
&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;using System;
using System.Collections.Generic;
using System.Text;

namespace MyPluginAssembly
{
  public class MyPlugin
  {
    public MyPlugin()
    {

    }

    public string Hello()
    {
      return "Hello";
    }
  }
}

&lt;/pre&gt;
&lt;p&gt;
This assembly needs to be compiled and for the sake of simplicity we’ll call it “MyPluginAssembly.dll”.
Copy this dll to the same directory as the MyAppDomain output folder. Next, we’ll
change the example a bit and load the assembly, do some reflection, run the Hello
method and print the result.
&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace MyAppDomain
{
  class Program
  {
    static void Main(string[] args)
    {
      AppDomain myDomain = null;
      try
      {
        myDomain = AppDomain.CreateDomain("Remote Domain");
        myDomain.UnhandledException += new UnhandledExceptionEventHandler(myDomain_UnhandledException);
        Worker remoteWorker = (Worker)myDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Worker).FullName);

        Console.WriteLine(remoteWorker.RunPlugin());

        PrintAssemblies(myDomain);
        PrintAssemblies(AppDomain.CurrentDomain);

      }
      catch(Exception ex)
      {
        myDomain_UnhandledException(myDomain, new UnhandledExceptionEventArgs(ex, false));
      }
      finally
      {
        if (myDomain != null)
        {
          Console.ForegroundColor = ConsoleColor.Red;
          Console.WriteLine("Unloading {0}", myDomain.FriendlyName);
          Console.ForegroundColor = ConsoleColor.Gray;
          AppDomain.Unload(myDomain);
        }
      }

      PrintAssemblies(AppDomain.CurrentDomain);


      Console.ReadLine();
    }

    static void myDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
      Exception ex = e.ExceptionObject as Exception;
      if (ex != null)
        Console.WriteLine(ex.Message);
      else
        Console.WriteLine("A unknown exception was thrown");
    }

    static void PrintAssemblies(AppDomain domain)
    {
      Console.ForegroundColor = ConsoleColor.Yellow;
      Console.WriteLine("Assemblies loaded in domain {0} are:", domain.FriendlyName);
      Console.ForegroundColor = ConsoleColor.Gray;
      foreach (var item in domain.GetAssemblies())
      {
        Console.WriteLine(item.FullName);
      }
    }
  }



  public class Worker : MarshalByRefObject
  {
    public Worker()
    {

    }

    public string DomainName
    {
      get
      {
        return AppDomain.CurrentDomain.FriendlyName;
      }
    }

    public string RunPlugin()
    {
      Assembly asm = Assembly.LoadFrom("MyPluginAssembly.dll");
      Type pluginType = asm.GetType("MyPluginAssembly.MyPlugin");
      object plugin = pluginType.GetConstructor(new Type[0]).Invoke(new object[0]);
      return (string)pluginType.GetMethod("Hello").Invoke(plugin, new object[0]);
    }

  }
}

&lt;/pre&gt;What
you’ll notice is that the first list will show that the remote’s plugin assembly is
also loaded in the local appdomain. But once the AppDomain is unloaded, the plugin
assembly is gone. &lt;img width="0" height="0" src="http://www.jeroenlandheer.com/Blog/aggbug.ashx?id=d7c03e9c-f1a8-4bd4-b49d-f9f86c49313e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
This website is sposored by &lt;a href="http://www.thewheel.nl"&gt;The Wheel Automatisering&lt;/a&gt;.</description>
      <comments>http://www.jeroenlandheer.com/Blog/CommentView,guid,d7c03e9c-f1a8-4bd4-b49d-f9f86c49313e.aspx</comments>
      <category>Programming</category>
    </item>
    <item>
      <trackback:ping>http://www.jeroenlandheer.com/Blog/Trackback.aspx?guid=8d33584c-33ef-4f39-8b37-e6fad60b8aa2</trackback:ping>
      <pingback:server>http://www.jeroenlandheer.com/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.jeroenlandheer.com/Blog/PermaLink,guid,8d33584c-33ef-4f39-8b37-e6fad60b8aa2.aspx</pingback:target>
      <dc:creator>Jeroen Landheer</dc:creator>
      <wfw:comment>http://www.jeroenlandheer.com/Blog/CommentView,guid,8d33584c-33ef-4f39-8b37-e6fad60b8aa2.aspx</wfw:comment>
      <wfw:commentRss>http://www.jeroenlandheer.com/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=8d33584c-33ef-4f39-8b37-e6fad60b8aa2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One of the requirements that I have on an application that I’m working on is that
the user can select a date easily when a textbox has focus. I wanted this to do in
such a manner that programmatically this can be done with minimum effort, and that
a few extra things are taken into account:
</p>
        <ul>
          <li>
Nullable dates (i.e. end dates) should be allowed with an empty text box 
</li>
          <li>
Not-nullable dates should default to the date of today 
</li>
          <li>
Multiple date pickers should be possible within the same form</li>
        </ul>
        <p>
          <strong>Ingredients</strong>
        </p>
        <p>
For this to work out, I’ve used the date picker control that’s available at <a title="http://jqueryui.com/" href="http://jqueryui.com/">http://jqueryui.com/</a> Besides
that, I’m using ASP.Net MVC 1.0
</p>
        <p>
          <strong>Creating an extension method for System.Web.Mvc.ViewUserControl</strong>
        </p>
        <p>
For the view, I’m using an extension method that’s called “DateField”. This allows
me to use the date field without having to use things like “RenderPartial” and creating
custom models. 
</p>
        <p>
This class looks like this:
</p>
        <pre class="brush: csharp;">public static class ViewUserControlDateFieldExtension
{
  public static string DateField(this IViewDataContainer control, string fieldName)
  {
    return DateField(control, fieldName, control.ViewData.Eval(fieldName) as DateTime?, false);
  }

  public static string DateField(this IViewDataContainer control, string fieldName, bool allowNulls)
  {
    return DateField(control, fieldName, control.ViewData.Eval(fieldName) as DateTime?, allowNulls);
  }

  public static string DateField(this IViewDataContainer control, string fieldName, DateTime? value)
  {
    return DateField(control, fieldName, value, false);
  }

  public static string DateField(this IViewDataContainer control, string fieldName, DateTime? value, bool allowNulls)
  {
    StringBuilder sb = new StringBuilder();
    sb.AppendFormat("&lt;input type=\"text\" name=\"{0}\" value=\"{1}\" class=\"datepicker\" /&gt;", fieldName, GetFieldValue(control, value, allowNulls));
    return sb.ToString();
  }

  private static string GetFieldValue(IViewDataContainer control, DateTime? value, bool allowNulls)
  {
    if (allowNulls)
    {
      if (value.HasValue)
        return value.Value.ToString("dd-MM-yyyy");
      else
        return String.Empty;
    }
    else
    {
      if (value.HasValue)
      {
        if (value.Value == DateTime.MinValue)
          return DateTime.Now.ToString("dd-MM-yyyy");
        else
          return value.Value.ToString("dd-MM-yyyy");
      }
      else
        return DateTime.Now.ToString("dd-MM-yyyy");
    }
  }
}
</pre>
        <p>
          <strong>Next, adding some jQuery script</strong>
        </p>
        <p>
Adding the script to the master page is easy. Just a few &lt;script&gt; tags and that’s
it. 
</p>
        <pre class="brush: xml;">&lt;link href="/themes/redmond/ui.all.css" type="text/css" rel="Stylesheet" /&gt;
&lt;script src="/Scripts/jquery-1.3.2.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script src="/Scripts/ui/ui.core.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script src="/Scripts/ui/ui.datepicker.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script src="/Scripts/ui/i18n/ui.datepicker-nl.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript" language="javascript"&gt;
  // Configure and add a date picker.
  $(function() {
  $(".datepicker").datepicker({
    changeMonth: true,
    changeYear: true
  });
  $(".datepicker").datepicker('option', { dateFormat: 'dd-mm-yy' });
  $.datepicker.setDefaults($.extend({ showMonthAfterYear: false }, $.datepicker.regional['nl']))
});
&lt;/script&gt;
</pre>
        <p>
          <strong>Finally, use the class</strong>
        </p>
        <p>
Using the class is as easy as using this little line of code for a date field:
</p>
        <pre class="brush: csharp;">&lt;% = this.DateField("EndDate", true) %&gt;
</pre>
        <p>
The result looks like this:
</p>
        <p>
          <a href="http://www.jeroenlandheer.com/Blog/content/binary/WindowsLiveWriter/AddingsomeUIelementswithjQuerytoanMVCapp_EE26/image_2.png">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.jeroenlandheer.com/Blog/content/binary/WindowsLiveWriter/AddingsomeUIelementswithjQuerytoanMVCapp_EE26/image_thumb.png" width="245" height="210" />
          </a>
        </p>
        <p>
The most nice part? It works in IE7, IE8, Opera, Chrome, FireFox and Safari. 
</p>
        <p>
          <strong>UPDATE: Why use IViewDataContainer</strong>
        </p>
        <p>
I had a question from someone who wanted to know why I choose to extend IViewDataContainer
in stead of WebControl/WebPage. The reason is simple. Both the System.Web.Mvc.ViewPage
en System.Web.Mvc.ViewControl implement IViewDataContainer. This makes the interface
the easiest target to implement. 
</p>
        <img width="0" height="0" src="http://www.jeroenlandheer.com/Blog/aggbug.ashx?id=8d33584c-33ef-4f39-8b37-e6fad60b8aa2" />
        <br />
        <hr />
This website is sposored by <a href="http://www.thewheel.nl">The Wheel Automatisering</a>.</body>
      <title>Adding some UI elements with jQuery to an MVC app</title>
      <guid isPermaLink="false">http://www.jeroenlandheer.com/Blog/PermaLink,guid,8d33584c-33ef-4f39-8b37-e6fad60b8aa2.aspx</guid>
      <link>http://www.jeroenlandheer.com/Blog/2009/06/05/AddingSomeUIElementsWithJQueryToAnMVCApp.aspx</link>
      <pubDate>Fri, 05 Jun 2009 21:03:17 GMT</pubDate>
      <description>&lt;p&gt;
One of the requirements that I have on an application that I’m working on is that
the user can select a date easily when a textbox has focus. I wanted this to do in
such a manner that programmatically this can be done with minimum effort, and that
a few extra things are taken into account:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Nullable dates (i.e. end dates) should be allowed with an empty text box 
&lt;li&gt;
Not-nullable dates should default to the date of today 
&lt;li&gt;
Multiple date pickers should be possible within the same form&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Ingredients&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
For this to work out, I’ve used the date picker control that’s available at &lt;a title="http://jqueryui.com/" href="http://jqueryui.com/"&gt;http://jqueryui.com/&lt;/a&gt; Besides
that, I’m using ASP.Net MVC 1.0
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Creating an extension method for System.Web.Mvc.ViewUserControl&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
For the view, I’m using an extension method that’s called “DateField”. This allows
me to use the date field without having to use things like “RenderPartial” and creating
custom models. 
&lt;/p&gt;
&lt;p&gt;
This class looks like this:
&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;public static class ViewUserControlDateFieldExtension
{
  public static string DateField(this IViewDataContainer control, string fieldName)
  {
    return DateField(control, fieldName, control.ViewData.Eval(fieldName) as DateTime?, false);
  }

  public static string DateField(this IViewDataContainer control, string fieldName, bool allowNulls)
  {
    return DateField(control, fieldName, control.ViewData.Eval(fieldName) as DateTime?, allowNulls);
  }

  public static string DateField(this IViewDataContainer control, string fieldName, DateTime? value)
  {
    return DateField(control, fieldName, value, false);
  }

  public static string DateField(this IViewDataContainer control, string fieldName, DateTime? value, bool allowNulls)
  {
    StringBuilder sb = new StringBuilder();
    sb.AppendFormat("&amp;lt;input type=\"text\" name=\"{0}\" value=\"{1}\" class=\"datepicker\" /&amp;gt;", fieldName, GetFieldValue(control, value, allowNulls));
    return sb.ToString();
  }

  private static string GetFieldValue(IViewDataContainer control, DateTime? value, bool allowNulls)
  {
    if (allowNulls)
    {
      if (value.HasValue)
        return value.Value.ToString("dd-MM-yyyy");
      else
        return String.Empty;
    }
    else
    {
      if (value.HasValue)
      {
        if (value.Value == DateTime.MinValue)
          return DateTime.Now.ToString("dd-MM-yyyy");
        else
          return value.Value.ToString("dd-MM-yyyy");
      }
      else
        return DateTime.Now.ToString("dd-MM-yyyy");
    }
  }
}
&lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;Next, adding some jQuery script&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Adding the script to the master page is easy. Just a few &amp;lt;script&amp;gt; tags and that’s
it. 
&lt;/p&gt;
&lt;pre class="brush: xml;"&gt;&amp;lt;link href="/themes/redmond/ui.all.css" type="text/css" rel="Stylesheet" /&amp;gt;
&amp;lt;script src="/Scripts/jquery-1.3.2.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src="/Scripts/ui/ui.core.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src="/Scripts/ui/ui.datepicker.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src="/Scripts/ui/i18n/ui.datepicker-nl.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type="text/javascript" language="javascript"&amp;gt;
  // Configure and add a date picker.
  $(function() {
  $(".datepicker").datepicker({
    changeMonth: true,
    changeYear: true
  });
  $(".datepicker").datepicker('option', { dateFormat: 'dd-mm-yy' });
  $.datepicker.setDefaults($.extend({ showMonthAfterYear: false }, $.datepicker.regional['nl']))
});
&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;Finally, use the class&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Using the class is as easy as using this little line of code for a date field:
&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;&amp;lt;% = this.DateField("EndDate", true) %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
The result looks like this:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.jeroenlandheer.com/Blog/content/binary/WindowsLiveWriter/AddingsomeUIelementswithjQuerytoanMVCapp_EE26/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.jeroenlandheer.com/Blog/content/binary/WindowsLiveWriter/AddingsomeUIelementswithjQuerytoanMVCapp_EE26/image_thumb.png" width="245" height="210"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
The most nice part? It works in IE7, IE8, Opera, Chrome, FireFox and Safari. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;UPDATE: Why use IViewDataContainer&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
I had a question from someone who wanted to know why I choose to extend IViewDataContainer
in stead of WebControl/WebPage. The reason is simple. Both the System.Web.Mvc.ViewPage
en System.Web.Mvc.ViewControl implement IViewDataContainer. This makes the interface
the easiest target to implement. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.jeroenlandheer.com/Blog/aggbug.ashx?id=8d33584c-33ef-4f39-8b37-e6fad60b8aa2" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
This website is sposored by &lt;a href="http://www.thewheel.nl"&gt;The Wheel Automatisering&lt;/a&gt;.</description>
      <comments>http://www.jeroenlandheer.com/Blog/CommentView,guid,8d33584c-33ef-4f39-8b37-e6fad60b8aa2.aspx</comments>
      <category>MVC</category>
      <category>Programming</category>
    </item>
    <item>
      <trackback:ping>http://www.jeroenlandheer.com/Blog/Trackback.aspx?guid=0f853661-d107-462b-9c4e-ec50ae523148</trackback:ping>
      <pingback:server>http://www.jeroenlandheer.com/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.jeroenlandheer.com/Blog/PermaLink,guid,0f853661-d107-462b-9c4e-ec50ae523148.aspx</pingback:target>
      <dc:creator>Jeroen Landheer</dc:creator>
      <wfw:comment>http://www.jeroenlandheer.com/Blog/CommentView,guid,0f853661-d107-462b-9c4e-ec50ae523148.aspx</wfw:comment>
      <wfw:commentRss>http://www.jeroenlandheer.com/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=0f853661-d107-462b-9c4e-ec50ae523148</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Microsoft will release a new programming language… er, 2 new programming languages
with .Net 4.0. One is called “F#”, the other one “M”. 
</p>
        <p>
F# is a functional programming language that made it’s appearance around the end of
2004, but became more popular in the last year. Now, F# is so successful it will make
it into .Net 4.0 and Visual Studio 2010.  
</p>
        <p>
The other language is ”M” which allows a developer to model the solution in to basic
blocks and verify that the code actually conforms to the model. 
</p>
        <p>
Both languages will mean a new steep learning curve for all those who are interested,
but that’s what developers do: we learn new things as we go along. A developer who
doesn’t learn can go and retire in about 5 years from now. 
</p>
        <p>
I’ve got the Visual Studio 2010 beta running, and I’ll be playing a bit with all this
:) 
</p>
        <p>
          <a href="http://www.jeroenlandheer.com/Blog/content/binary/WindowsLiveWriter/Ohdearanotherlanguagemakesitinto.Net_AE04/image_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.jeroenlandheer.com/Blog/content/binary/WindowsLiveWriter/Ohdearanotherlanguagemakesitinto.Net_AE04/image_thumb.png" width="644" height="457" />
          </a>
        </p>
        <img width="0" height="0" src="http://www.jeroenlandheer.com/Blog/aggbug.ashx?id=0f853661-d107-462b-9c4e-ec50ae523148" />
        <br />
        <hr />
This website is sposored by <a href="http://www.thewheel.nl">The Wheel Automatisering</a>.</body>
      <title>Oh dear, another language makes it into .Net</title>
      <guid isPermaLink="false">http://www.jeroenlandheer.com/Blog/PermaLink,guid,0f853661-d107-462b-9c4e-ec50ae523148.aspx</guid>
      <link>http://www.jeroenlandheer.com/Blog/2009/05/25/OhDearAnotherLanguageMakesItIntoNet.aspx</link>
      <pubDate>Mon, 25 May 2009 14:23:00 GMT</pubDate>
      <description>&lt;p&gt;
Microsoft will release a new programming language… er, 2 new programming languages
with .Net 4.0. One is called “F#”, the other one “M”. 
&lt;/p&gt;
&lt;p&gt;
F# is a functional programming language that made it’s appearance around the end of
2004, but became more popular in the last year. Now, F# is so successful it will make
it into .Net 4.0 and Visual Studio 2010.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
The other language is ”M” which allows a developer to model the solution in to basic
blocks and verify that the code actually conforms to the model. 
&lt;/p&gt;
&lt;p&gt;
Both languages will mean a new steep learning curve for all those who are interested,
but that’s what developers do: we learn new things as we go along. A developer who
doesn’t learn can go and retire in about 5 years from now. 
&lt;/p&gt;
&lt;p&gt;
I’ve got the Visual Studio 2010 beta running, and I’ll be playing a bit with all this
:) 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.jeroenlandheer.com/Blog/content/binary/WindowsLiveWriter/Ohdearanotherlanguagemakesitinto.Net_AE04/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.jeroenlandheer.com/Blog/content/binary/WindowsLiveWriter/Ohdearanotherlanguagemakesitinto.Net_AE04/image_thumb.png" width="644" height="457"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.jeroenlandheer.com/Blog/aggbug.ashx?id=0f853661-d107-462b-9c4e-ec50ae523148" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
This website is sposored by &lt;a href="http://www.thewheel.nl"&gt;The Wheel Automatisering&lt;/a&gt;.</description>
      <comments>http://www.jeroenlandheer.com/Blog/CommentView,guid,0f853661-d107-462b-9c4e-ec50ae523148.aspx</comments>
      <category>Programming</category>
      <category>Visual Studio 2010</category>
    </item>
  </channel>
</rss>