WCF, NSubstitute, and Autofac

Recently I've been working on the code samples for an upcoming 1/2-day course I'm giving at HDC. While reviewing some code, I stopped on this method:

public ReadOnlyCollection<string> GetGroups(IIdentity identity)
{
    var channel = new ChannelFactory<IGroupsService>().CreateChannel();

    return channel.Use<ReadOnlyCollection<string>>(() =>
    {
        return new ReadOnlyCollection<string>(
            (from response in channel.RetrieveGroups(
                new RetrieveGroupsRequest[] { new RetrieveGroupsRequest(identity.Name) })
            where response.Request.UserName == identity.Name
            select response.Groups).First());
    });
}

What I didn't like about it was the fact that within the method, I was getting a reference to a IGroupsService-based object via ChannelFactory. That smelled like a coupling I could break by adding some dependency injection (like I'm doing with the identity argument). But here's another problem. Use() is an hand-rolled extension method I use a lot in WCF-based code as it wraps code blocks that use a service and "properly" shuts down the service (see this article for details). Now, ChannelFactory will return a proxy based on the interface given, but it also has that proxy implement ICommunicationObject. So, my extension method is typed for object and then does a check to ensure that the given reference is of an ICommunicationObject type (if it doesn't, it throws an exception). Using typical mocking libraries like RhinoMocks, I can't give it a set of interfaces and have it cruft up a mock or stub that implements all those interfaces [1]. Sure, I could create a helper interface:

public interface IGroupsCommunicationObjectService : IGroupsService, ICommunicationObject { }

And feed that into my mocking framework of choice, but that feels klutzy.

So, could NSubstitute and Autofac help out here?

See, part of the reason I'm revisiting the code samples is to swap out RhinoMocks and Castle Windsor for NSubstitute and Autofac. I have nothing against my original frameworks of choice, but I've been reading good things about the new kids on the block, and I wanted to give them a test drive. Plus, I wanted my attendees to use a library that wasn't as well-known as the popular choices I originally made. As you'll see, NSubstitute and Autofac have features that made my changes easy to do.

First, let's change my method around a bit:

public ReadOnlyCollection<string> GetGroups(IIdentity identity, 
    IGroupsService service)
{
    return service.Use<ReadOnlyCollection<string>>(() =>
    {
        return new ReadOnlyCollection<string>(
            (from response in service.RetrieveGroups(
                new RetrieveGroupsRequest[] { new RetrieveGroupsRequest(identity.Name) })
            where response.Request.UserName == identity.Name
            select response.Groups).First());
    });
}

That's the easy part. Now let's see what the happy path test looks like for GetGroups():

[TestMethod]
public void GetGroups()
{
    var name = Guid.NewGuid().ToString("N");
    var group = Guid.NewGuid().ToString("N");

    var identity = Substitute.For<IIdentity>();
    identity.Name.Returns(name);

    var channel = Substitute.For<IGroupsService, ICommunicationObject>();
    channel.RetrieveGroups(Arg.Any<RetrieveGroupsRequest[]>()).Returns(info =>
    {
        var request = (info[0] as RetrieveGroupsRequest[])[0];
        Assert.AreEqual(name, request.UserName);
        return new RetrieveGroupsResponse[] { 
            new RetrieveGroupsResponse(request, new string[] { group }) };
    });

    var repository = new GroupsRepository();
    var results = repository.GetGroups(identity, channel);
    
    Assert.AreEqual(1, results.Count);
    var result = results[0];
    Assert.AreEqual(group, result);
    channel.Received().RetrieveGroups(Arg.Any<RetrieveGroupsRequest[]>());
}

One thing I really like about NSubstitute is that it completely ditches the epic fakes/stubs/mocks/test-double war that's been tearing apart the software development community for centuries. OK, I kid, but honestly, I really never understood why there's been so much made over the terminology. I get the differences, but it seemed to make things more confusing and less pragmatic. NSubstitute just creates "substitutes", and I really like that term. You can create expectations if you want (that's what Received() does), or you don't have to. It's all up to you.

Furthermore, NSubstitute makes it brutally simple to make a substitute that implements multiple interfaces. The returned substitute is strongly-typed for the first interface listed in the generic definitions, but trust me, it implements ICommunicationObject, and that's exactly what I want. This also has a nice unexpected benefit in that this also act just like CreateChannel() does from ChannelFactory - i.e. it acts like the interface you give it, but it also is ICommunicationObject-based - you just don't "see" that.

OK, so I have my unit test in place. In the real world, how do I resolve my dependencies? In my test, I'm not using a container to resolve the dependencies, so let's see Autofac in action with the "real" service creation:

var builder = new ContainerBuilder();
builder.Register(_ => 
    (new ChannelFactory<IGroupsService>()).CreateChannel()).As<IGroupsService>();
var container = builder.Build();

Beautiful. Autofac allows you to define how the dependencies will be created via anonymous methods, so it's very simple to create the channel via normal WCF means. This doesn't even begin to show the power and flexibility that Autofac has - you really owe it to yourself to dive into Autofac's API.

By the way, if I wanted to use my channel substitute in the container, I'd just do something like this:

var builder = new ContainerBuilder();
builder.RegisterInstance<IGroupsService>(channel);
var container = builder.Build();

I hope this post has showed you some of the cool things you can do with NSubstitute and Autofac. I'm sold on them (until something cooler comes along :) ).

[1] Or at least I couldn't find the magic API to do it.

* Posted at 08.24.2010 11:38:18 PM (Last Update: 08.25.2010 12:12:13 AM) | 0 comments | Link | RSS *

"Creative Evolutionary Systems"

I finished this book a couple days ago. The book is a high-level overview of the work researchers have done in trying to create computer program that are "creative" using a number of techniques and ideas. The areas covered range from robots to music to art to architecture. The essays described the difficulties in making programs "creative", especially as it pertains to feedback (which in a lot of cases had to be done by humans in relatively slow ways).

Overall I felt this book was hit-and-miss. The chapters on music and antenna design were really interesting, but the architecture chapters didn't resonate with me at all. The conversations are technical but they don't cover a lot of the details and I felt myself wanting to learn more. There's a CD that comes with the book and I haven't played around with any of the programs yet so that may help yield some further insights.

If you can find a copy of the book that you can borrow at a relatively cheap price, it's an interesting read, so go for it. However, it's not one that I feel is a "must" to have plowed through.

* Posted at 08.19.2010 11:09:05 PM | 0 comments | Link | RSS *

Twin Cities Code Camp 9 is Gearing Up to be HUGE

I've been with TCCC since its inception, since ... well, I was the one that started it :). Over the last 4 years, it has grown and expanded slowly but surely. With TCCC9, it's now so big that it's 2 days long! Oct. 9th and 10th are dates this time. You can register for the event here. The current session list is here. Frankly, the session list is awesome and I'm still taking session submissions! I'll have to make some cuts, and that sucks because the topics are relevant and interesting, but that means (hopefully) the quality and quantity will be on the high side.

Hope to see you all there! :)

* Posted at 08.19.2010 07:30:15 PM (Last Update: 08.19.2010 07:38:47 PM) | 0 comments | Link | RSS *

Why Should Unit Testing Frameworks Handle Unhandled Exceptions?

A couple of days ago I was glancing though a book on unit testing sitting on a fellow dev's desk, and one of the early examples showed how you can write a unit test all by yourself. The author was trying to show the concept without introducing a framework at the same time and I liked that. What I didn't like was the way exception handling was done:

try
{
   // Unit test code goes here...
}
catch(Exception e)
{
   // Reporting the exception goes here...
}

Ugh. I so cannot stand when I see books and articles do this. This is such a bad practice in coding - the number of times I write code to handle the general exception is ... well, I honestly can't remember when I've done it. It's not completely verboten - there are valid cases when you have to - but there's so rare that in 99.999999856% of your exception handlers you should not do this.

But wait - this is a knee-jerk reaction on my part. Think of all the unit testing frameworks you've used. They usually do this exact thing. In other words, you have a bunch of tests in your system, and suddenly a change you made causes a test to fail somewhere else due to an unhandled exception. However, you'll see all tests reported at the end with one failing.

But hold on ... think about this for a second.

Why should that have happened?

We've always talked about failing fast ... OK, I usually say that in my talks, so I won't say "we" as in "all developers". But I believe it's true - the quicker you fail, the better. I personally feel apps should just die quickly (with as much logging information as possible in the face of an unhandled exception) rather than swallow exceptions (and no, showing a message box to a user showing them the exception's message is not handling the exception).

Why shouldn't unit test frameworks act the same way?

If you're test has an Assert and that fails, fine, report that the user. But if the code has an unhandled exception, then ... well, stop! So what if it is a unit test. Unit tests should be written with the same standards and principles as you do with your "regular" code, so why do unit test frameworks try to "keep on truckin'" in the face of an unhandled exception?

I realize that I've completely glossed over isolation - it's possible that frameworks can put the test in its own AppDomain or process to allow other tests to run at the cost of performance (or maybe some of them do this already). But I'm starting to wonder if unit test frameworks are doing it "right".

* Posted at 08.15.2010 03:46:42 PM | 0 comments | Link | RSS *

Flagged Links #79

* Posted at 08.15.2010 03:26:42 PM | 0 comments | Link | RSS *

Flagged Links #78

* Posted at 08.11.2010 09:23:21 PM | 0 comments | Link | RSS *

Flagged Links #77 (Double Issue)

* Posted at 08.04.2010 03:38:19 PM | 0 comments | Link | RSS *

"A Simple Plan"

I finished this book last week over my vacation at some cabins with family. It's a tale where three people (2 brothers and a friend) stumble across over 4 million dollars in a crashed plane. Their initial plan is to wait 6 months to see if anything is mentioned about the plane, and if all is clear, they split the money. The majority of the book chronicles the slow but steady descent into horror as each of them unravel the plan via really bad decisions.

I don't want to tell you too much about the book because it would ruin the effect of the storytelling. It's that good. I had a really hard time putting the book down. It's a train wreck of choices that spiral completely out of control, and I found myself wanting to see just how far it would go. It's really easy to read at a beach (or anywhere else for that matter). Grab a copy and dive in.

* Posted at 08.01.2010 11:46:49 AM (Last Update: 08.12.2010 12:30:47 PM) | 1 comment | Link | RSS *

Quote
"The whole world seems to live under the banner: 'Freedom is wonderful--but only for me.'" Isaac Asimov
Twitter History
follow me on Twitter
Blog History