Use Closures to Put C# on a Diet

I enjoy playing with state machines. They are simple enough to implement quickly, and complex enough to give the implementation language a little workout. Followers of this blog will know that I’ve enjoyed using Finite State Machines to explore CoffeeScript.

But, when I look at the search terms leading to my blog, I see that people want to see FSMs implemented in C#, C++, or even VB. About the only language I haven’t seen people looking for is CoffeeScript. I’m not too surprised, since most people searching for FSM implementations are probably students trying to cheat get help on their homework. I doubt any professors are accepting CoffeeScript implementations.

When I see these search results, I consider quickly posting a solution in the requested language. I don’t mind if students crib solutions from me. I’m a big believer in learning by example. Certainly if by looking at my FSMs I can save one student from writing a switch statement, then I’ll consider it a public service. On the other hand, I’m not really interested in producing solutions by language on demand. Its not so much that I’m worried about students reading my solutions, as much as it is that implanting FSMs over and over again in different languages isn’t very interesting on its own merits.

While I was refactoring the String.Contains FSM for my previous post, I saved a few lines by taking advantage of closure. My inspiration for this refactoring came from a question one of the attendee’s asked at my CoffeeScript Crash Course presentation at SoCalCodeCamp. If you watch the video you will hear him ask, “Does the @ imply closure, and if so why?” As I said in my presentation and on this blog, I’m no expert at CoffeeScript or JavaScript, so I can’t claim to have instantly grasped the context of his question. However, as I listened to it again, and listened to his comments to another attendee, I began to understand why he asked the question. The result was the new implementation I wrote about in my last post.

C# also supports closure, so I began to wonder what a C# String.Contains implementation would look like if we wanted to use as much closure as possible. I’ve implemented this machine in C# and C++ before, but I’m intrigued enough by the closure idea to try C# again.

Getting Started

This sample should be simple, Visual Studio seems like overkill, so I’m going to code it in Sublime Text 2 and use the C# compiler on the command line.

csc .\StringCompare.cs 

If StringCompare.cs contains this skeleton program, it should compile to a do-nothing program:

public class Program
{
    public static void Main(params string[] args)
    {
    }
}

Rules

In our CoffeeScript implementation we have a class called Rule with two subclasses. Lets see how this looks in C#:

public class Rule
{
    public Rule(int currentState, char inputChar, int nextState)
    {
        this.NextState = nextState;
        this.Match = (machineState, readChar) =>
        {
            return currentState == machineState && readChar == inputChar; 
        };
    }

    public int NextState { get; private set; }
    public Func<int, char, bool> Match { get; private set; }
}

Remember, our goal is to use as much closure as possible, so if we can avoid declaring data properties, we will. All of our data comes in through the constructor, so we can create a lambda expression that closes over the currentState and inputChar and use it as our Match function. We still need to declare the Match function and its signature, but there is no need to create instance properties for the data. For NextState we could define a Func<int>, but that would have no benefit compared to a simple int property, so we’ll use a property.

That’s all fine in theory, but does it work? Let’s write a little test in the Main function.

public class Program
{
    public static void Main(params string[] args)
    {
        var myRule = new Rule(0, '1', 1);
        Console.WriteLine(myRule.Match(0,'1'));
        Console.WriteLine(myRule.Match(1,'1'));
    }
}

As expected, this test prints True followed by False. It’s clear from this test that closure works just as well in constructors as anywhere else. Having satisfied my intuition, I can delete this test code If I want to and move on to implementing the specialized TrapRule and ReturnRule classes.

public class TrapRule : Rule
{
    public TrapRule(int currentState)
        : base(currentState, (char)0, currentState)
    {
        this.Match = (machineState, readChar) =>
        {
            return currentState == machineState;
        };
    }
}

Like the CoffeeScript implementation, I pass currentState to the base implementation twice. However, I can’t pass null for a char value in C#. Instead, I pass in the null character 0. Its also interesting to note that I don’t need to make Match virtual, and I don’t need to override it. All I need to do is make the setter protected so that the subclass can replace the implementation. We can update the test in Main to verify that this subclass works.

public class Program
{
    public static void Main(params string[] args)
    {
        var myRule = new TrapRule(0);
        Console.WriteLine(myRule.Match(0,'1'));
        Console.WriteLine(myRule.Match(1,'1'));
    }
}

As expected, we see True printed, followed by False. Next, we can implement the ReturnRule.

public class ReturnRule : Rule
{
    public ReturnRule(int currentState, char inputChar)
        : base(currentState, inputChar, 0)
    {
        this.Match = (machineState, readChar) =>
        {
            return currentState == machineState && readChar != inputChar;
        };
    }
}

We actually don’t need to pass currentState and inputChar to the base class, because it only needs to know the nextState. However, it doesn’t hurt to pass it either. Once again, the child class replaces the Match implementation with one appropriate for the return rule. As before, we can update our test to verify the ReturnRule behavior.

public static void Main(params string[] args)
{
    var myRule = new ReturnRule(0, '0');
    Console.WriteLine(myRule.Match(0,'0'));
    Console.WriteLine(myRule.Match(0,'1'));
}

As expected, this prints False followed by True. In theory, we’ve implemented Rule classes that should work with a String.Contains implementation. We need to see how this works with a machine implementation.

Machine

In the CoffeeScript implementation, I saw no benefit in converting the createMachine function into a class. In C#, I thought I might be able to do something similar with dynamic. It turns out that this doesn’t work though. The C# compiler produces error CS0828 because you cannot assign a lambda expression to an anonymous type property. I don’t use dynamic very often, so this is news to me. It seems I’m already learning more about C# through this exercise.

So, with this restriction in place, I will need to create a class to implement the machine.

public class Machine 
{
    public Machine(Rule[] transitionRules, int currentState, int[] acceptanceStates)
    {
        this.ReadAll = (input) =>
        {
            foreach(var inputChar in input)
            {
                Read(inputChar);
            }
        };
        this.Read = (inputChar) => 
        {
            foreach(var rule in transitionRules) 
            {
                if (rule.Match(currentState, inputChar))
                {
                    currentState = rule.NextState;
                    return;
                }
            }
            currentState = -1;
        };
        this.AcceptedInput = () => Array.IndexOf(acceptanceStates, currentState) >= 0;
    }

    public Action<string> ReadAll { get; private set; }
    public Action<char> Read { get; private set; }
    public Func<bool> AcceptedInput { get; private set; }
}

This implementation compiles, but does it work? We’ll need some test code to determine for sure. To do that we’ll need to implement createSearchMachine and testMachine. These implementations should be possible using Func<> instances in Main without having to create classes.

Here is createSearchMachine:

Func<string, Machine> createSearchMachine = (searchString) =>
{
    var source = searchString.ToCharArray();
    var states = Enumerable.Range(0, source.Length);
    var rules = states.Select(x => new Rule(x, source[x], x + 1))
        .Concat(states.Where(x => x != source.Length).Select(x => new ReturnRule(x, source[x])))
        .Concat(new []{ new TrapRule(source.Length) });
    return new Machine(rules.ToArray(), 0, new[]{ source.Length });
};

It’s interesting that, while slightly more verbose and noisy, C# supports a nearly identical implementation as CoffeeScript. Here is testMachine:

Action<string, string> testMachine = (input, searchString) =>
{
    var machine = createSearchMachine(searchString);
    machine.ReadAll(input);
    Console.WriteLine("{0}--{1}", machine.AcceptedInput(), input);
};

Now we can finally run the machine and see how it works.

var target = "operating system";
testMachine("Windows is an operating system installed on many machines.", target);
testMachine("Welcome to the operating room, the Doctor is just finishing his martini.", target);

And our output is just what we expect:

C:\...\gist-3063755> .\StringContains.exe 
True--Windows is an operating system installed on many machines. 
False--Welcome to the operating room, the Doctor is just finishing his martini. 

Great, Closure All The Things!

No, not really.  In CoffeeScript/JavaScript closures are the norm and expected.  In C# the question you have to ask yourself is why would you close over everything.  Keep in mind that, although you do not declare classes with data members, they still exist.  The compiler generates them for you, so its not like you’ve “saved” anything by using closure.  Maybe closures make your code harder to reflect into, since the compiler will use unspeakable names to refer to the classes it generates.  This obscurity might appeal to some, but for me it’s simply a learning exercise.  I hope you learned something too.

You can check out the finished code at this gist.

Shadows vs. Overrides

Photo Credit: ludovic.celle

I spent some time recently thinking about the difference between override methods, which replace virtual methods (as far as outside callers are concerned), and new methods, which merely hide base class methods (not necessarily virtual methods either). While refactoring the other day I stumbled onto something I thought was clever, but that all hinges on whether shadowing and overriding behave the way I think they do.  So it seemed worthwhile to research it a bit.

After a simple Google search I found plenty of examples, but none that confirmed or denied all of my intuitions about the behavior of each method type.  As is often the case, it was more instructive to start a test project and explore the behavior myself.

Override Basics

Lets start with an example from csharpfaq.

public class Base
{
    public virtual void SomeMethod()
    {
    }
}

public class Derived : Base
{
    public override void SomeMethod()
    {
    }
}

That’s rather dull, we can jazz it up a bit.

public class BasicLogger
{
    protected virtual void WriteMessage(string source, string message)
    {
        EventLog.WriteEntry(source, message);
    }

    public void CallOutTheHour(string post, string hour)
    {
        this.WriteMessage(post, hour + " o'clock and all is well.");
    }
}

public class TraceLogger : BasicLogger
{
    private readonly TraceSource Log;
    public TraceLogger(TraceListener listener)
    {
        this.Log = new TraceSource("LoggerApp");
        this.Log.Switch.Level = SourceLevels.All;
        if (listener != null)
        {
            this.Log.Listeners.Add(listener);
        }
    }

    protected override void WriteMessage(string source, string message)
    {
        this.Log.TraceEvent(
            TraceEventType.Information, 
            0, 
            "{0}: {1}", 
            source,
            message);
    }
}

On versions of Windows that have UAC (Vista+ or 2008+) BasicLogger is basically untestable/unusable unless you want to run as administrator. That should make our tests clear, I should get an exception anytime BasicLogger.WriteMessage is called.

[TestClass]
public class ShadowsVsOverride
{
    [TestMethod]
    [ExpectedException(typeof(SecurityException))]
    public void TestBasicLogger()
    {
        new BasicLogger().CallOutTheHour("One", "Six");
    }
}

Likewise, we expect that TraceLogger instances will write out the message.

[TestMethod]
public void TestTraceLogger()
{
    using (var listener = new StringWriter())
    {
        new TraceLogger(new TextWriterTraceListener(listener))
            .CallOutTheHour("One", "Six");                
        Assert.AreEqual(
            "LoggerApp Information: 0 : One: Six o'clock and all is well." + Environment.NewLine, 
            listener.ToString());
    }
}

Note that CallOutTheHour is declared on the base, but that the WriteMessage method it actually calls is on the derived class. This is what people mean when they say that the virtual method is replaced, the base class can’t even call its own WriteMessage method. Once something is overridden, only the derived class has the option of calling the original method. We could write a method like this on TraceLogger:

public void WriteToEventLogDirect(string source, string message)
{
    base.WriteMessage(source, message);
}

We can see that this “works” by observing the exception.

[TestMethod]
[ExpectedException(typeof(SecurityException))]
public void TestWriteDirectlyToEventLog()
{
    new TraceLogger(null).WriteToEventLogDirect("Foo", "Bar");
}

To beat this to death we can see that it doesn’t matter what type the calling code thinks its using, the override replaces the virtual.

[TestMethod]
public void TestCasting()
{
    using (var listener = new StringWriter())
    {
        TraceLogger t = new TraceLogger(new TextWriterTraceListener(listener));
        BasicLogger target = t;

        target.CallOutTheHour("One", "Six");
        Assert.AreEqual(
            "LoggerApp Information: 0 : One: Six o'clock and all is well." + Environment.NewLine,
            listener.ToString());
    }
}

Shadowing Basics

Shadowing, using the Shadows keyword in Visual Basic, or the new keyword in C#, “merely hides” the method in the base class. What does this mean? Lets modify our loggers and see. First I’m going to make BasicLogger.WriteMessage a non-virtual method.

protected void WriteMessage(string source, string message)
{
    EventLog.WriteEntry(source, message);
}

This generates a compiler error:

'LoggerApp.Shadow.TraceLogger.WriteMessage(string, string)': cannot override inherited member 'LoggerApp.Shadow.BasicLogger.WriteMessage(string, string)' because it is not marked virtual, abstract, or override 

The Visual Basic compiler is even more to the point.

'Protected Overrides Sub WriteMessage(source As String, message As String)' cannot override 'Protected Sub WriteMessage(source As String, message As String)' because it is not declared 'Overridable' 

Although, in both languages “it” is ambiguous. We know that “it” refers to the base class method, because that’s all I changed.  We can resolve the error by removing the override declaration.

protected void WriteMessage(string source, string message)
{
    this.Log.TraceEvent(
        TraceEventType.Information, 
        0, 
        "{0}: {1}", 
        source,
        message);
}

Removing the override keyword in TraceLogger changes the error into a warning in C#.

'LoggerApp.Shadow.TraceLogger.WriteMessage(string, string)' hides inherited member 'LoggerApp.Shadow.BasicLogger.WriteMessage(string, string)'. Use the new keyword if hiding was intended. 

Visual Basic also generates a warning, but doesn’t suggest the Shadows keyword, instead it suggests Overloads.

sub 'WriteMessage' shadows an overloadable member declared in the base class 'BasicLogger'. If you want to overload the base method, this method must be declared 'Overloads'. 

I guess we would have to look at the IL to see if there is a difference between Shadows and Overloads in this situation, but I’m not going to go that far today. For now we’ll add the new keyword to our TraceLogger.WriteMessage declaration and see how our tests run.

protected new void WriteMessage(string source, string message)
{
    this.Log.TraceEvent(
        TraceEventType.Information, 
        0, 
        "{0}: {1}", 
        source,
        message);
}

When using shadowing, TestCasting and TestTraceLogger both fail with exceptions. In fact, every method now throws exceptions, its just that the other two tests were expecting exceptions, and these two were not. It seems now that BasicLogger.WriteMessage is always called. Before exploring why, I’ll decorate these two tests with ExpectedExceptionAttributes so that they pass, then we’ll write some new tests to continue to explore shadowing.

CallOutTheHour is declared on BasicLogger and so is “underneath” the shadow cast by TraceLogger. TraceLogger is doing its best to hide the method with its own implementation, but it can’t hide it from BasicLogger‘s own methods. However, from any code that recognizes TraceLogger as a TraceLogger (including TraceLogger itself), the shadow prevents the BaseLogger.WriteMessage method from being executed. Lets give TraceLogger its own public method to see that it can still call its own method:

public class TraceLogger : BasicLogger
{
    private readonly TraceSource Log;
    public TraceLogger(TraceListener listener)
    {
        // ...
    }

    protected new void WriteMessage(string source, string message)
    {
        // ...
    }

    // ...

    public void CallOutAlarm(string source, string message)
    {
        this.WriteMessage(source, "To Arms! It's " + message + "!");
    }
}

And here’s the test to verify:

[TestMethod]
public void TestSibling()
{
    using (var listener = new StringWriter())
    {
        new TraceLogger(new TextWriterTraceListener(listener))
            .CallOutAlarm("One", "Robin Hood");
        Assert.AreEqual(
            "LoggerApp Information: 0 : One: To Arms! It's Robin Hood!" + Environment.NewLine,
            listener.ToString());
    }
}

TraceLogger can still call the BaseLogger method using the base keyword. We don’t need a new test for this because our existing TestWriteDirectlyToEventLog test already covers that scenario.

Shadowing has an interesting capability which overriding lacks. You can use shadowing to change the visibility of a method. This lets us make WriteMessage public on TraceLogger if we like.

public new void WriteMessage(string source, string message) 

After this change, we have no errors or warnings, and our tests still pass. But now we can test WriteMessage directly if we want to.

[TestMethod]
public void TestWriteMessage()
{
    using (var listener = new StringWriter())
    {
         new TraceLogger(new TextWriterTraceListener(listener))
            .WriteMessage("Foo", "Bar");
        Assert.AreEqual(
            "LoggerApp Information: 0 : Foo: Bar" + Environment.NewLine,
            listener.ToString());
    }
}

This capability is interesting, but confusing. Compared to overriding, there is more mental baggage to keep track of, you have to remember what side of the shadow each piece of code is on, and you have to remember what interface the caller is using. Callers that create objects like this:

var t = new TraceLogger(...); TraceLogger v = new TraceLogger(...); 

Will get different behavior than those who declare the reference like this:

BasicLogger b = new TraceLogger(...); 

That’s something to think about before jumping into method hiding.

Considerations

Some people, when learning about shadowing, become very consternated. They think hiding methods is a bad idea, and it probably is. Then they go one step too far and use is as an example of bad design in .NET. But, it has nothing to do with .NET, C++ has always had the ability to hide non-virtual methods. Consider this code from SO#5289774

class Foo;
struct B : A<Foo> {
  void doSomething();
};

// and in the .cpp file:
#include "Foo.h"

void B::doSomething() {
  A<Foo>::doSomething();
}

Instead of just letting this happen, .NET has a keyword that lets you do it explicitly, and the compiler has a warning that might give you a clue that what you’re about to do is not what you intend. But the point in both languages is that hiding methods is a confusing implementation choice and should be used sparingly if at all. In simple cases like our logger, we should have just added another public method instead of using shadowing to increase the visibility of WriteMessage. If you only want increased visibility for testing purposes, you can subclass in your test project and place the extra accessor method there.

Tip: Modern INotifyPropertyChanged

Photo Credit: Sanne Roemen

I don’t get much chance to work on the desktop or in Silverlight so I haven’t had too many opportunities to work with the INotifyPropertyChanged interface.  While refactoring an old class toward the Single Responsibility Principle today, I thought to myself “I need an event here,” and since the event was related to a property changing I decided to implement INotifyPropertyChanged instead of using a basic event.

Being rusty with INotifyPropertyChanged I used Google to search for any cool tricks people have come up with since the last time I gave this interface any thought.  I think the most cutting edge way to do it is probably with AOP, but there are some other cool tricks too.  Maybe this is old hat, but it’s new to me.

Generic Setter

There are a few posts out there about using generic setters.  Some of them smell bad.  This one smells good to me: INotifyPropertyChanged, the Anders Hejlsberg Way, by Dan Rigby.  Tips from Anders are always nice :).

Here is what the setter looks like:

private void SetProperty<T>(ref T field, T value, string name)
{
    if (!EqualityComparer<T>.Default.Equals(field, value))
    {
        field = value;
        var handler = PropertyChanged;
        if (handler != null)
        {
          handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

The only issue I have with the implementation is that it still requires a magic string.  We’d like to avoid magic strings because they aren’t code, and because they aren’t code they are usually ignored by refactoring tools and can’t be checked by the compiler.

No Magic

Several posts explain how to get rid of the magic string using a lambda expression.  I used this article as reference: Silverlight/WPF: Implementing PropertyChanged with Expression Tree, by Michael Sync.  Michael’s post takes a different approach and just passes the lambda into the setter.  Later he shows some extension methods that can eliminate the need to specify the type parameter explicitly.  But, when I combined his technique with Dan’s I didn’t find the need to specify the type parameter, since the compiler can infer this information from the field and value parameters.

Here’s what we get after combining the two:

private void SetProperty<T>(ref T field, T value, Expression<Func<T>> member)
{
    Contract.Requires(member != null, "member must not be null.");
    var me = member.Body as MemberExpression;
    if (me == null)
    {
        throw new InvalidOperationException("member.Body must be a MemberExpression");
    }

    if (!EqualityComparer<T>.Default.Equals(field, value))
    {
        field = value;
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(me.Member.Name));
        }
    }
}

Here is how we use it:

public int Threshold
{
    get
    {
        return this.threshold;
    }
    private set
    {
        this.SetProperty(ref this.threshold, value, () => this.Threshold);
    }
}

Its no longer refactoring resistant, yay!  I think the error-checking in the setter is a little ugly though.

Cleaner Code with .NET 4.5

I actually found this article first: INotifyPropertyChanged, The .NET 4.5 Way, by Dan Rigby, then followed a link there to the Anders-inspired example.  In the post, Dan shows how to use the CallerMemberNameAttribute (new in .NET 4.5) to eliminate the need for the expression tree.  Without the expression tree, we don’t need the error checking code related to the tree and we can implement a cleaner version of SetProperty.  Be sure to check out Dan’s article as he mentions a couple more useful attributes coming in .NET 4.5.

Stop Guessing About MEF Composition And Start Testing

Diagnosing MEF Failures | SoCalCodeCamp @ CSU Fullerton | 1/29/2012

I gave my first talk at a Code Camp last weekend. The topic was “Diagnosing MEF Failures” at it was well received by the 5 attendees.  A recording of the talk is embedded at the top of this post, and the direct link is just below, along with the slides and demo code.  This blog post compliments the talk by providing a step by step guide about how to test your MEF composition using ApprovalTests and Microsoft’s CompositionDiagnostics library.

Finally, I revisted this subject in June 2012.  If you only want to know the easiest way to setup composition tests, read MEF Composition Tests, Redux instead.  If you’re interested in knowing how everything works under the hood, read this article first, then read the June article.

Why?

Diagnosing MEF composition failure is tricky, especially when parts have two or more nested dependencies.  In this scenario, MEF’s error messages aren’t very helpful.  MEF was unable to satisfy one or more parts in the chain, but the error message points you to the part at the top of the chain, to really fix the problem you need to know about the bottom of the chain.   If you start by looking where the error message sends you, you can end up feeling like you’re on a wild goose chase because nothing appears to be wrong with that part.

Recognizing this problem, the MEF team created the a static diagnostics library as a “Sample”, but when MEF was integrated into the BCL with .NET 4, this useful library never made it in.  You can still get the code from the MEF CodePlex site, along with a shell that allows you to define directory or assembly catalogs from the command line and analyze the parts within.  This shell is useful and flexible (for example, you could use it to examine deployed parts in production without changing any code) but sometimes tedious to use.  An alternate shell (Visual MEFx) brings some nice GUI touches to the concept.  The GUI makes it much easier to play with what if scenarios while examining the collection of parts.

Either of these tools can be used to analyze real, deployed compositions, even when dealing with parts authored by a third party.  That’s a really powerful concept.  But for some MEF users (myself included), third parties are not a big concern.  I’m using MEF to compose a collection of known parts, so I can say with confidence what the composition should look like.  Sometimes I might want to play out a what-if scenario, but most of the time I just want some assurance that all my parts are there, and therefore all my application’s expected behaviors will be there.

Ideally, I’d like to automate this assurance without relying on a GUI, or trying to spin up a separate process during integration testing.  Finally, it would be great if I could be assured that my composition looked correct without having to write one test for every part that should be in the container.  How I achieve these goals is the subject of this post.

Background

If you don’t know about ApprovalTests you really should take a moment to learn about them.  Read about this library at http://approvaltests.sourceforge.net/, and be sure to listen to the Herding Code podcast.  You don’t need to understand much about ApprovalTests to follow the recipe I plan to lay out below, but even if you aren’t interested in MEF at all, you should still check out ApprovalTests.

Presumably if you are reading this you are already familiar with MEF, but if not, get started here: “What is MEF?”.  You don’t have to read the whole thing to start getting the point of what MEF is for, maybe just the first few sections.  Follow that with the MEF Programming Guide on CodePlex.

If you would rather read than watch my video, I primarily drew from two references while putting together my talk.  Part 13 of the MEF programming guide is about Debugging and Diagnostics.  Finally, this entry on Daniel Plaisted’s Blog is a great reference which includes background on why MEF fails in general, quite a few corner cases, and an overview of live and static debugging tools.  My talk focuses on using the tools, so read Daniel’s blog if you’re really interested in studying MEF failure.

Since Daniel covers MEFx and Visual MEFx, I wont discuss them here, instead I’ll focus on presenting the recipe for testing MEF composition with ApprovalTests.

What You Will Need

  • For starters, you’ll need a project that uses MEF, but since you are here I’ll assume you already have that.
  • You’ll need to download ApprovalTests and reference it in your test project.  There is a version on NuGet, but its not always up to date with the latest release from the SourceForge site.  The recipe should work with 1.0.11 or greater, so its up to you if you want the latest and greatest.
  • You’ll need a version of the CompositionDiagnostics library.  A quick way to get your hands on a binary copy is to download MEFx.  The MEFx zip contains two files, one is a command line shell, and the other is the library.  You can obtain the source by downloading MEF Preview 9.  Note that there are MEF 2 previews also in the release list, you want the preview from MEF 1.

The CompositionDiagnostics source may be useful if you run into any issues with imports showing up out of order on different machines.  If you have this problem, add this method to the CompositionInfoTextFormatter:

private static string GetPartDefinitionKey(object definition)
{
    if (definition == null)
        return null;
    var compositionElement = definition as ICompositionElement;
    return compositionElement != null ?
        compositionElement.DisplayName :
        definition.ToString();
}

Then update the Write() method to order the PartDefinitionInfos by this “key”.

Test Setup

I’m using MSTest, it works fine for me.  If you have a favorite test framework, this shouldn’t be too hard to adapt.

If you don’t have a test project for your solution, set one up.  It will be important to keep your test and production catalogs in sync.  You don’t want to fix a problem in test and still have your composition fail in production.  I use directory catalogs, so I keep my catalogs in sync using a simple pre-build event in the test project properties:

copy /y “$(SolutionDir)$(SolutionName)\bin\x86\Debug\*.dll” “$(TargetDir)”

Add references to ApprovalTests.dll and ApprovalUtilities.dll.

Unzip the MEFx zip file, or compile the code yourself.

Grab the Microsoft.ComponentModel.Composition.Diagnostics.dll file, and place it near your solution (a lib folder would be a good option) then take a reference to the library.

Add a test class to the solution and call it whatever makes sense to you, I’ll use the name “IntegrationTest” in my example.

Import these namespaces into your IntegrationTest file.

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.IO;
using System.Reflection;
using ApprovalTests;
using ApprovalTests.Reporters;
using Microsoft.ComponentModel.Composition.Diagnostics;

Add a UseReporterAttribute to your test class.   DiffReporter is my favorite:

[TestClass]
[UseReporter(typeof(DiffReporter))]
public class IntegrationTest

The CompositionDiagnostics library provides us with a few new types.  The most interesting to me is the CompositionInfo class.  This is where the magic happens.  We create a catalog and a container as usual, then instantiate an instance of CompositionInfo, passing the catalog and container into the constructor.  I find it useful to put this into its own method, since I usually have at least two integration tests.

private static CompositionInfo GetCompositionInfo()
{
    var catalog = new DirectoryCatalog(".");
    var host = new CompositionContainer(catalog);
    var compositionInfo = new CompositionInfo(catalog, host);
    return compositionInfo;
}

Now you can add a test method.  Here’s the code, followed by an explanation:

[TestMethod]
public void DiscoverParts()
{
    try
    {
        using (var stringWriter = new StringWriter())
        {
            CompositionInfoTextFormatter.Write(
                GetCompositionInfo(),
                stringWriter);
            Approvals.Verify(stringWriter.ToString());
        }
    }
    catch (ReflectionTypeLoadException ex)
    {
        Array.ForEach(
            ex.LoaderExceptions,
            lex => Console.WriteLine(lex.ToString()));
        throw;
    }
}

The CompositionDiagnostics library provides another useful class, the CompositionInfoTextFormatter, which we can use to create a text representation of the data in the CompositionInfo.  The CompositionInfo class does all the heavy lifting.  We use the method Approvals.Approve to verify the text representation, more on this later, for now its enough to know that this line takes the place of an “Assert” call in an ordinary unit test.

This test also catches the ReflectionTypeLoadException. Type loading problems can cause your test to fail when the CompositionInfo is under construction. Therefore, you would never reach the ApprovalTest. MSTest will catch this and dump the exception in the test result, but the really interesting information on that exception is in the LoaderExceptions property which isn’t shown by default. So, in the catch block each loader exception is dumped to the console before allowing the exception to go on it’s merry way. This saves the extra step of rerunning the test under the debugger just to drill into the LoaderExceptions.

That’s it for the first test, if you’ve been following along you should be able to run it.

The Results

When you run the test for the first time, it will fail.  This is not unusual for ApprovalTests.  The ApprovalTest library needs “approved” output to verify the test output against.  Since we used the DiffReporter, you are notified of the failure when a diff tool launches showing output on one side and a blank slate on the other.  (If nothing happens, you probably need TortiseSVN, which provides the default diff tool.  You can switch to NotepadLauncher if you decide you don’t like the idea of installing TortiseSVN just for this purpose.  Other reporters are supported, but that’s outside the scope of this entry.)

MEF1

You can flip the left and right sides to make it easier to read.

So what is this?  Briefly, the diagnosis begins by looking at the Parts property on the catalog, examining the metadata for each, and eventually tries to compose each part defined in the catalog.  This will uncover any problems with the composition by throwing exceptions.  The analyzer catches the exceptions, and stores them in a data structure along with the other metadata.  Any parts that fail for reasons not related to importing other parts have the potential to be the root cause of the composition failure.  Each will be marked as a [Primary Rejection] by the text formatter.  Exceptions and the other metadata will also be printed with each part.

That’s the sad path.  On the happy path, your composition succeeds and each part is still listed, along with some metadata and information about which parts satisfied nested imports, if any.  So, in our test, we get the CompositionInfo, and format the data using the CompositionInfoTextFormatter.  The output is captured by a StringWriter, and passed to Approvals.Approve() for comparison.  If the output is correct, we should see no exceptions listed, no rejections, and each part [SatisfiedBy] the exports we expected to be imported.  If so, we can right click on the “received” file and choose “Use this whole file”.  Save.  It is now approved.  Rerunning the test should result in a pass.

If the composition has problems, we need to work on those problems until the output looks right, just as we would in any other TDD scenario.  Once it is right, approve it so it can be checked in the future.  Whenever any change is made to the composition (expected or not) this test will fail and let you know that you either need to approve the new composition, or resolve the unexpected failure.

Since the ReflectionTypeLoadException causes the test to fail before the approval stage, you should look at the trace output or test results when these occur.  Your loader exceptions will likely be MissingMethodExceptions with messages explaining that certain methods have no implementation.  Whichever part is meant to provide those implementations cannot load, and you may have to do some detective work to figure out why.  Often I find that these problems are related to parts expecting different versions of the same assemblies, or that the parts refer to assemblies that are unavailable.

Another Test

I usually have this next test in my IntegrationTest as well.

[TestMethod]
public void InstantiateService()
{
  try
  {
    Approvals.Verify(
      GetCompositionInfo().Host.GetExportedValues<IPizzaMaker>(),
      s => s.GetType().FullName);
  }
  catch (ReflectionTypeLoadException ex)
  {
    Array.ForEach(
      ex.LoaderExceptions,
      lex => Console.WriteLine(lex.ToString()));
    throw;
  }
}

I look at it now and I wonder why.  This test will grab all instances of a certain type of part, compose them, and return them.  ApprovalTests will approve the list.  This doesn’t really do anything new compared to the full dump of the CompositionInfo in DiscoverParts.

I think that over time I must have become over zealous with the Don’t Repeat Yourself principle and used the GetCompositionInfo() method when I shouldn’t have.  The original form of this test was probably this:

[TestMethod]
public void InstantiateService()
{
  try
  {
    var catalog = new DirectoryCatalog(".");
    var host = new CompositionContainer(catalog);
    Approvals.Verify(
      host.GetExportedValues<IPizzaMaker>(),
      s => s.GetType().FullName);
  }
  catch (ReflectionTypeLoadException ex)
  {
    Array.ForEach(
      ex.LoaderExceptions,
      lex => Console.WriteLine(lex.ToString()));
    throw;
  }
}

So, what’s the difference/use of this second version?  In the version that uses GetCompositionInfo, the container and catalog construction happen inside the method, then are passed to a CompositionInfo.  Later, the test just used the container (accessed through the Host property) to ask for the IPizzaMaker instances.  So the construction of the CompositionInfo was a waste, but you might live with that for the sake of staying DRY.  However, since we know that the CompositionInfo can die during construction, its more than just a waste, it’s a potential source of test failure that has nothing to do with the ability to instantiate IPizzaMakers.

In the second version we construct the host without bothering with the CompositionInfo, and we avoid ReflectionTypeLoadExceptions unless they have something to do with IPizzaMaker.  So this test might tell you something interesting if making IPizzaMakers was your primary concern, but it wont give you the type of root cause analysis provided in the CompositionDiagnostics output.  So using both can potentially give you a smidge more insight into your composition.

If you reuse GetCompositionInfo to access the host, it tends to fail in concert with the DiscoverParts test, and so tells you nothing new.

MEF 2

In MEF 2, the InstantiateService test has the potential to take center stage, while the DiscoverParts test will be more of a niche player.  This is because the MEF team has made big improvements to the baked in diagnostics and exception messages.  First of all, MEF always knew what the root cause was, it just failed to tell you about it in the error message.  In MEF 2 Preview 5, the composition exception indicates the primary rejection at the top of a chain of failures leading all the way down to the part you asked for.

By default, the container will still wait for you to ask for a part that requires the rejected part (or the rejected part itself) before any exception is thrown.  This is part of MEFs “Stable Composition” feature.  You can disable this feature by passing the CompositionOptions.DisableSilentRejection option to the container’s constructor.  The result will be that MEF will throw an exception as soon as it rejects the part.  You will definitely want to use this option on the container used for integration tests, and if you aren’t working with third parties, disabling silent rejection is recommended on your production container as well.

When you run InstantiateService with silent rejection disabled, you should get an exception if any part in the container would be rejected, not just the IPizzaMakers.  This allows InstantiateService to detect a larger class of failures in MEF 2 compared to MEF 1.

The DiscoverParts test will still have its niche in MEF 2.  This test will remain useful in detecting missing optional parts.  A part that is optional and missing will not throw an exception even when silent rejection is disabled.  Although other parts want to import the optional parts, they don’t “depend” on them to operate, since classes that import optional parts should all be able handle the case where the parts aren’t available.  Since its missing (meaning—not in the catalog) there’s no way it could have a problem itself and throw an exception.

So if the part is optional should your test pass or fail?  Its up to you to decide, but remember that the whole premise of this test strategy is that you already know what the composition should look like.  You could have a collection of three services you want hosted that work together in an assembly line fashion. You might want to reserve the right to increase the number of steps in the assembly line in the future so you use [ImportMany] to get the whole collection.  Now you’ve just made your imports optional, but do you really want to deploy your application if service 2 of 3 is missing?  The DiscoverParts test can detect this for you, but “noisy” rejection can’t.  It’s a niche, but it’s a niche I find myself in, so I think the DiscoverParts test will remain useful even after MEF 2 arrives.

Conclusion

Really, I just hope that someone will find this idea useful.  Feel free to run with it and let me know if you can think of any other strategies for testing composition.  In particular I’d be interested to hear ways that people have found for testing scenarios with third parties or in production.  If you are interested in additional thoughts from me on the subject, please read: MEF Composition Tests, Redux.

Thanks for reading.