Archive for the 'Development' Category

Problems running xUnit 1.1 under TestDriven.NET on 64-bit Windows

Tuesday, March 24th, 2009

I ran into a problem today trying to run xUnit tests under TestDriven.NET on my 64-bit Windows (7) install.

I had xUnit installed (with TestDriven.NET support enabled). I also had the TestDriven.NET 2.14 release installed (which is the latest stable build).

My test project had a reference to xunit.dll and my test methods were decorated with the [Fact] attribute.

But for some reason, when I tried to run the tests using TestDriven.NET, it would give the dreaded 0 passed, 0 failed, 0 skipped result, meaning it didn’t run any tests.

I’m not sure what the problem was, but the solution was simple: Install the latest TestDriven.NET beta build (currently 2.19.2409).

Apparently there is an issue with TestDriven.NET on 64-bit Windows (alluded to on the xUnit 1.1 release page).

Not sure if the problem is xUnit-specific or it occurs with other test frameworks as well.

Proper Disposing of System.Net.Mail.MailMessage

Friday, October 31st, 2008

I ran into this today while working on some client code.

Some of the overrides for System.Net.Mail.Attachment take a Stream parameter. The Attachment class will hold on to that stream until you send the corresponding MailMessage.

To ensure that the stream is cleaned up properly you need to call Dispose() on the MailMessage instance when you are finished with it:
using (MailMessage message = BuildMessage()) { SmtpClient client = new SmtpClient(); client.Send(message); }
Using .NET Reflector, you can see that disposing the MailMessage disposes each Attachment, which will in turn close each Stream.

If you don’t dispose the MailMessage, you are at the mercy of the garbage collector. For a FileStream that can cause unexpected, and seemingly unrelated, problems.

C# Extension Methods

Thursday, August 7th, 2008

I was explaining to a friend how to use extension methods and wrote up this quick sample.

namespace Foo.Extensions { public static class StringExtensions { public static string Truncate(this string value, int maxLength) { if (value.Length > maxLength) return value.Substring(0, maxLength - 3) + "..."; return value; } } }

To use the extension method:

using Foo.Extensions; // IMPORTANT! namespace Foo { public static class Program { public static void Main(string[] args) { string longText = "this is some really long text!!!"; Console.WriteLine(longText.Truncate(20)); } } }

The magic happens when you add the this keyword to the first parameter of the static method. This tells the compiler to add the method to the specified type (string is this example). The method behaves as an instance method, though your extension method can only access public members of the type.

You can also call the extension method the old way: StringExtensions.Truncate(longText, 20);

It’s important to note that you MUST add a using statement to import the namespace where you defined the extension method (Foo.Extensions in this example), otherwise the compiler (and intellisense) won’t add the methods to the specified types.

Extension methods are one of the most useful additions to C# 3.0. They are simple to use and in many cases you can convert an existing method to be an extension method without breaking existing code.

.NET Reflector auto update

Thursday, July 24th, 2008

I love .NET Reflector. It’s an indispensable programming tool.

Unfortunately it has one big flaw: it’s auto update feature is not optional.

I regularly work disconnected, either because I’m not near a hotspot or because I’m running a VM without internet access.

If Reflector determines that it is out-of-date it will refuse to run until you update it. This is a huge pain because I usually don’t hit the problem unless I need to use Reflector.

Yes, I know complaining about free software is lame, but please Lutz, make the update functionality optional. I promise I’ll update the next time I’m connected.

Update: Red Gate has acquired .NET Reflector. Please visit my forum post and share your opinion!

JavaScriptSerializer non-generic Deserialize method

Thursday, July 10th, 2008

I was messing around with the ASP.NET MVC Preview 3 the other evening and ran into a “problem” with the JavaScriptSerializer. The class provides two methods for deserializing an object from JSON data:

public T Deserialize<T>(string data); public object DeserializeObject(string data);

A notable omission from the API is a non-generic method for deserializing to a specific type, i.e.:

public object Deserialize(Type type, string data);

This method would be useful when dynamically deserializing objects, using reflection for instance.

Digging around with Reflector I found that the generic method just delegates to an internal helper, passing the generic parameter T as typeof(T). It would be a simple matter then to provide the necessary overload that accepts the Type directly.

Hopefully the ASP.NET team will add the missing overload, but in the meantime I decided to "cheat" with the following extension method:

public static class JavaScriptSerializerExtensions { public static object Deserialize(this JavaScriptSerializer serializer, Type type, string data) { Type serializerType = typeof(JavaScriptSerializer); object[] args = new object[] { serializer, data, type, serializer.RecursionLimit, }; return serializerType.InvokeMember( "Deserialize", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, Type.DefaultBinder, null, args); } }

MVC and DLR presentations at ALT.NET

Tuesday, October 9th, 2007

Some pretty cool presentations from the ALT.NET conference by Scott Guthrie and Scott Hanselman. Check out Scott Hanselman’s blog post for the details.

Unfortunately he links to the Silverlight video player for the videos which apparently doesn’t work for a lot of people. Here are direct links to the .WMV files (hosted by Microsoft):

ScottGu’s presentation on MVC:
ScottGuOnMVCatALTNET.wmv

ScottHa’s presentation on MVC+DLR:
ScottHaOnDLRandMVCatALTNET.wmv

Enjoy!

const string vs. static string

Sunday, May 20th, 2007

There was an email thread going around the office not too long ago debating whether it is more efficient to use string constants or static readonly strings (in C#). An example was given that seemed to indicate that the static strings were better:

public class Sample { static readonly string StaticString = "StaticString"; const string ConstString = "ConstString"; public void SetValues(StringCollection strings) { strings[StaticString] = "foo"; strings[ConstString] = "bar"; } public void GetValues(StringCollection strings) { string value1 = strings[StaticString]; string value2 = strings[ConstString]; } }

The disassembly of that code shows something surprising:

public class Sample { // Fields private const string ConstString = "ConstString"; private static readonly string StaticString = "StaticString"; // Methods public void GetValues(NameValueCollection values) { string text1 = values[StaticString]; string text2 = values["ConstString"]; } public void SetValues(NameValueCollection values) { values[StaticString] = "foo"; values["ConstString"] = "bar"; } }

It doesn't look like the const string is being used at all, while it's obvious that the static string is. This can't be right. Let's take a look at the IL:

.class public auto ansi beforefieldinit Sample extends [mscorlib]System.Object { .method private hidebysig specialname rtspecialname static void .cctor() cil managed { .maxstack 8 L_0000: ldstr "StaticString" L_0005: stsfld string TestStringConstantsLibrary.Sample::StaticString L_000a: ret } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 L_0000: ldarg.0 L_0001: call instance void [mscorlib]System.Object::.ctor() L_0006: ret } .method public hidebysig instance void GetValues(class [System]System.Collections.Specialized.NameValueCollection values) cil managed { .maxstack 8 L_0000: ldarg.1 L_0001: ldsfld string TestStringConstantsLibrary.Sample::StaticString L_0006: callvirt instance string [System]System.Collections.Specialized.NameValueCollection::get_Item(string) L_000b: pop L_000c: ldarg.1 L_000d: ldstr "ConstString" L_0012: callvirt instance string [System]System.Collections.Specialized.NameValueCollection::get_Item(string) L_0017: pop L_0018: ret } .method public hidebysig instance void SetValues(class [System]System.Collections.Specialized.NameValueCollection values) cil managed { .maxstack 8 L_0000: ldarg.1 L_0001: ldsfld string TestStringConstantsLibrary.Sample::StaticString L_0006: ldstr "foo" L_000b: callvirt instance void [System]System.Collections.Specialized.NameValueCollection::set_Item(string, string) L_0010: ldarg.1 L_0011: ldstr "ConstString" L_0016: ldstr "bar" L_001b: callvirt instance void [System]System.Collections.Specialized.NameValueCollection::set_Item(string, string) L_0020: ret } .field private static literal string ConstString = string('ConstString') .field private static initonly string StaticString }

Same odd result, though we can see that the const string is defined as a static field (with the literal modifier instead of the initonly modifier). What gives? I refuse to believe that const strings are duplicated all over the assembly. Opening the assembly in a hex editor (I used Visual Studio's Binary Editor), you can see that there are only 2 instances of the string (not the 3 you would expect):

In fact, if we add the following method to our class:

public void WriteConsole() { Console.WriteLine("ConstString"); Console.WriteLine("ConstString"); Console.WriteLine("ConstString"); Console.WriteLine("ConstString"); Console.WriteLine("ConstString"); Console.WriteLine("ConstString"); Console.WriteLine("ConstString"); }

We can see that it does not add any additional strings to our assembly. There are still only the 2 instances:

So, const string is not as bad as it initially looks. I am curious why there are 2 instances of the string though, and why the field isn’t referenced…

Getting the name of a builtin Windows security object

Tuesday, May 15th, 2007

It’s not obvious how to do this in .NET, but it’s actually pretty easy once you decipher the documentation.

The two classes you need are in the System.Security.Principal namespace:

You need to create a new instance of a SecurityIdentifier using the constructor that takes a WellKnownSidType enum value. The WellKnownSidType value specifies the built-in security object you are interested in.

// Assume using System.Security.Principal SecurityIdentifier si = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);

Given the instance of the SecurityIdentifier, you obtain the name via the Translate() method, passing typeof(NTAccount) and casting the result to an NTAccount instance.

NTAccount acct = (NTAccount)si.Translate(typeof(NTAccount));

The Value property of the NTAccount instance contains the name of the security group or user.

Console.WriteLine(acct.Value);

And for bonus points, here's a PowerShell function to do the same thing:

function GetWellKnownAccountName([string]$wellKnownSidType) { $si = new-object System.Security.Principal.SecurityIdentifier( [System.Security.Principal.WellKnownSidType]$wellKnownSidType, $null) $acct = $si.Translate([System.Security.Principal.NTAccount]) return $acct.Value }

Sample usage:

PS> GetWellKnownAccountName("BuiltinAdministratorsSid") BUILTIN\Administrators