«
May 2009
»
Answer to "NUnit isn't running VS10 code"
I just posted my first answer to stackoverflow. Brian Ball was getting the following error when trying to load a dll built using VS 2010 beta into the NUnit GUI:
This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded. You may be attempting to load an assembly build with a later version of the CLR than the version under which NUnit is currently running.
My answer was:
I've downloaded the NUnit 2.5 source and opened the VS2008 solution in the VS2010 beta. Once the conversion finished I opened all the projects and changed the target framework setting for all the projects to ".NET Framework 4.0". I then built the solution without any errors. I can now use the NUnit GUI app to run tests built for .NET 4.0. I've not done exhaustive testing of this build so there may be problems, but for my purposes it works fine.
UPDATE
It is not necessary to rebuild NUnit. I discovered that if you add the following to the relevant NUnit application config file you can run a test dll built for .NET 4.0. Under <configuration> add:
<startup> <requiredRuntime version="v4.0.20506" /> </startup>
and under <runtime> add:
<loadFromRemoteSources enabled="true" />
Just adding the requireRuntime element is insufficient and results in an security related error message mentioning the loadFromRemoteSources switch. I found something about the switch on this social.msdn post, where David DeWinter wrote:
Caveat: I'm not on the security team but will attempt to answer this nonetheless...
What's happening here is that the build tasks for Silverlight are attempting to load an assembly that, in previous versions of the CLR, would classify it as a partial trust assembly based on its evidence (e.g. its zone) according to CAS policy.
In CLR 4.0, CAS policy is totally deprecated and is not even enabled by default. Under the circumstances, though, it appears the CLR throws an Exception when what would be a partial trust load in CLR 2.0 is a full trust load in CLR 4.0.
The loadFromRemoteSources switch the Exception message refers to is in the runtime element under configuration and looks like this:
<runtime>
<loadFromRemoteSources enabled="true|false" />
</runtime>
This will not enable legacy CAS policy but will allow you (or, in this case, the build system) to load remote assemblies with the same permissions as the host AppDomain. In this case it seems as though you could modify the configuration for the build system (which I assume in this case would be Visual Studio: %ProgramFiles%\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe.config) to enable this switch.
If you don't want to modify that configuratino then you can set the environment variable COMPLUS_EnableLegacyCASPolicy to 1, which will enable CAS Policy that was present in CLR 2.0 and also allow Silverlight to load this task.
Hope that helps. David
Tip: Convert Value or Reference to Sequence of Length One
In the previous post I originally created the sequences based on a single value by creating an array. For example:
static Expr Nil()
{
return s => new string[] { s };
}
However this deviates a bit from the spirit of Linq, adds an unneccessary implementation detail, the fact that an array implements IEnumerable<T>, and hard-codes the string type into the expression. The neater way to do it is to use Enumerable.Repeat():
static Expr Nil()
{
return s => Enumerable.Repeat(s, 1);
}
Functional Style Regex Engine in C# Revisited
In January 2007 I posted about a Functional Style Regex Engine in C#. This was an exercise in using iterators and anonymous functions in C#. I decided it was time to see if it was possible to rewrite the code using Linq.
To recap, the goal is to be able to specify a regular expression in a functional style like this:
// c(a|d)+r
Rgx.Expr e =
Rgx.Seq(Rgx.Char('c'),
Rgx.Seq(Rgx.Plus(Rgx.Alt(Rgx.Char('a'), Rgx.Char('d'))),
Rgx.Char('r')));
foreach (string r in e("cdar"))
Console.WriteLine("Match with remainder: {0}", r);
Calling an instance of Expr returns an enumeration of all the matches which start at the beginning of the input string. When each of the functions is called it returns a lambda expression which takes a string parameter. The expression returns an enumeration containing the remainder for every match on the string. For example, if the lambda expression generated by Rgx.Char('x') is passed the string "xyz", the enumeration returned by the expression will contain the single string "yz", this being the remainder from the match on the character 'x'.
The rewritten class turns out to be quite neat compared to the original version which required some hackiness because the yield statement cannot be used in an anonymous block. Here it is:
using System;
using System.Collections.Generic;
using System.Linq;
class Rgx
{
public delegate IEnumerable<string> Expr(string s);
static Expr Nil()
{
return s => Enumerable.Repeat(s, 1);
}
static public Expr Seq(Expr l, Expr r)
{
return s => l(s).SelectMany(x => r(x));
}
static public Expr Alt(Expr l, Expr r)
{
return s => l(s).Concat(r(s));
}
static public Expr Star(Expr e)
{
return s => Nil()(s).Concat(Seq(e, Star(e))(s));
}
static public Expr Plus(Expr e)
{
return Seq(e, Star(e));
}
static public Expr Char(char c)
{
return s => s.Length > 0 && s[0] == c
? Enumerable.Repeat(s.Substring(1), 1)
: Enumerable.Repeat("", 0);
}
}
The implementation of Seq() made me think the most. The enumeration of match remainders from the left-hand side of the sequence is processed by the right-hand side of the sequence by using the SelectMany() function, i.e. each string in the output from the left-hand side is passed to the expression on the right-hand side, each call to the right-hand expression resulting in zero or more match remainders.
Again, this is definitely not the way to implement regular expression matching, but just an exercise in using Linq.
Alternative Syntax for Member Calls on C# Dynamic Types
XML-RPC.NET is essentially concerned with making statically typed calls to XML-RPC endpoints, using interfaces as contract definitions in a similar way to WCF. However the new dynamic type in .NET 4 makes it possible to provide a clean way of making dynamically typed calls, for example like this:
dynamic client = new XmlRpcClient("http://someXmlRpcEndpont");
int returnValue = client.Add(2, 3);
The DynamicObject class in the System.Dynamic namespace makes implementing a dynamic class straightforward:
using System.Dynamic;
class XmlRpcClient : DynamicObject
{
string endpoint;
public XmlRpcClient(string endpoint)
{
this.endpoint = endpoint;
}
public object Invoke(string methodName, object[] args)
{
return 5; // actually make call to XML-RPC endpoint here
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args,
out object result)
{
result = Invoke(binder.Name, args);
return true;
}
}
However, the method name in XML-RPC can be an arbitrary string which is not necessarily representable as a token in C#, for example "samples.Add". JavaScript handles this case by providing an alternative syntax to access a member via a string and then make a call on it, for example:
obj["foo"]() // get member 'foo' and call it
The dynamic type of C# does not support this, at least in the current beta, but it can be implemented:
using System.Dynamic;
class XmlRpcClient : DynamicObject
{
// ...
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes,
out object result)
{
result = (Func)(args => Invoke(indexes[0] as string, args));
return true;
}
public delegate object Func(params object[] args);
}
So making this code possible:
dynamic client = new XmlRpcClient("http://someXmlRpcEndpont");
int returnValue = client["samples.Add"](2, 3);
Windows 7 RC in VMWare Fusion
I installed Windows 7 RC in VMWare Fusion today (on an iMac with 2G of memory running Mac OS X 10.4). I followed the instructions on this post on the Team Fusion blog. "Windows Easy Install" blue-screened the guest machine so I tried a custom install which worked fine.
I then installed the Visual Studio 2010 beta and found this was very sluggish with a lot of display problems. Configuring the guest machine with 3D display switched off improved the performance and fixed the display issues.