A Dutch software developer living in Chile
| | Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|
| 28 | 1 | 2 | 3 | 4 | 5 | 6 | | 7 | 8 | 9 | 10 | 11 | 12 | 13 | | 14 | 15 | 16 | 17 | 18 | 19 | 20 | | 21 | 22 | 23 | 24 | 25 | 26 | 27 | | 28 | 29 | 30 | 31 | 1 | 2 | 3 | | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Search
Navigation
Categories
Blogroll
|

Monday, July 27, 2009
A very simple GZip command line tool
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.
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)) > 0)
{
target.Write(buffer, 0, count);
}
}
private static void ShowUsage()
{
Console.WriteLine("Usage: GZip compress | decompress sourceFileName targetFileName");
}
}
}
Monday, July 27, 2009 3:02:34 PM (Pacific SA Standard Time, UTC-04:00)
Programming
World’s smallest web server
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…
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);
Always nice to have ;)
Monday, July 27, 2009 1:21:45 PM (Pacific SA Standard Time, UTC-04:00)
Programming

Sunday, June 07, 2009
Running code in a different AppDomain
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?
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!)
Let’s start with a very simple example:
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;
}
}
}
}
What you see here is:
- An application domain is created
- A value is sent from the new application domain back to the local domain.
- We have a strongly-typed reference to the remote object
In this example, the remote domain is running with the same privileges as the local domain.
Let’s crash…
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:
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();
}
}
}
Loading assemblies in the remote application domain
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.
First, we create a simply plugin assembly:
using System;
using System.Collections.Generic;
using System.Text;
namespace MyPluginAssembly
{
public class MyPlugin
{
public MyPlugin()
{
}
public string Hello()
{
return "Hello";
}
}
}
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.
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]);
}
}
}
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.
Sunday, June 07, 2009 12:43:50 PM (Pacific SA Standard Time, UTC-04:00)
Programming

Friday, June 05, 2009
Adding some UI elements with jQuery to an MVC app
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:
- Nullable dates (i.e. end dates) should be allowed with an empty text box
- Not-nullable dates should default to the date of today
- Multiple date pickers should be possible within the same form
Ingredients
For this to work out, I’ve used the date picker control that’s available at http://jqueryui.com/ Besides that, I’m using ASP.Net MVC 1.0
Creating an extension method for System.Web.Mvc.ViewUserControl
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.
This class looks like this:
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("<input type=\"text\" name=\"{0}\" value=\"{1}\" class=\"datepicker\" />", 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");
}
}
}
Next, adding some jQuery script
Adding the script to the master page is easy. Just a few <script> tags and that’s it.
<link href="/themes/redmond/ui.all.css" type="text/css" rel="Stylesheet" />
<script src="/Scripts/jquery-1.3.2.js" type="text/javascript"></script>
<script src="/Scripts/ui/ui.core.js" type="text/javascript"></script>
<script src="/Scripts/ui/ui.datepicker.js" type="text/javascript"></script>
<script src="/Scripts/ui/i18n/ui.datepicker-nl.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
// 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']))
});
</script>
Finally, use the class
Using the class is as easy as using this little line of code for a date field:
<% = this.DateField("EndDate", true) %>
The result looks like this:

The most nice part? It works in IE7, IE8, Opera, Chrome, FireFox and Safari.
UPDATE: Why use IViewDataContainer
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.
Friday, June 05, 2009 5:03:17 PM (Pacific SA Standard Time, UTC-04:00)
MVC | Programming

Monday, May 25, 2009
Oh dear, another language makes it into .Net
Microsoft will release a new programming language… er, 2 new programming languages with .Net 4.0. One is called “F#”, the other one “M”.
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.
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.
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.
I’ve got the Visual Studio 2010 beta running, and I’ll be playing a bit with all this :)

Monday, May 25, 2009 10:23:00 AM (Pacific SA Standard Time, UTC-04:00)
Programming | Visual Studio 2010