Monday, November 26, 2012

The all new coding guidelines for C# 3.0, 4.0 and 5.0 have been published!

After 50000 downloads and the recent final release of Visual Studio 2012 / C# 5.0 it was about time to do a thorough update of the C# Coding Guidelines. Although most of the guidelines have been preserved, I’ve tried to rewrite several of them using a less formal and less verbose writing style. I’ve also improved the rational for some of them, shortened the introduction section, but added a refactoring heuristic I picked up from this blog post.

Other minor improvements include getting rid of the vague term identifier, applying the correct usage of the terms arguments and parameters, adding more cross-references between guidelines and adding various links to relevant articles. On the esthetic side, I’ve changed all code snippets to Consolas, reduced the line-spacing a bit, and changed the accent color to allow this version to stand out more from previous versions.

So which guidelines were changed?

  • Added a warning to AV1001 “Only create a constructor that returns a useful object” about potentially violating AV1000 and AV1561.
  • AV1008 “Mark classes that only contain static members as static” now promotes avoiding static classes at all rather than just marking it as static.
  • Added a reference to the Command Query Separation principle to AV1105 “Use a method instead of a property”.
  • Added a reference to the new .NET 4.5 read-only collection interfaces to AV1130 “Return an IEnumerable<T> or ICollection<T> instead of a concrete collection class”.
  • Renamed AV1135 “String, list and collection properties should never return a null reference” to include methods and parameters in addition to properties
  • Rephrased AV1140 “Consider replacing properties using primitive types to use rich value objects” to clarify that I was talking about domain-specific types.
  • Remove the incorrect examples from AV1515 “Don’t use "magic” numbers”
  • Renamed AV1521 “Initialize variables at the point of declaration” to make it clear we want variables to be declared and initialized as a late as possible.
  • Removed the 'method' part of AV1532 “Don’t use nested loops in a method” to say that nested loops should be avoid everywhere.
  • Renamed AV1535 “Add a block after all flow control keywords, even if it is empty” so that it includes concrete keywords rather than the vague 'flow control keywords'
  • Added a reference to AV1553 “Only use optional parameters to replace overloads” about Eric Lippert’s post on optional parameter corner cases.
  • Removed an example from AV1720 “Name methods using verb-object pair” because it conflicted with some of the LINQ extension methods introduced in .NET 3.0.
  • Rewrote and renamed AV1725 “Name namespaces according a well-defined pattern” to clearly explain the valid aspects of a namespace rather than emphasizing a particular pattern.
  • Changed the example in AV1735 “Use a verb or verb phrase to name an event” to use a generic event handler delegate.
  • Added a reference to to the .NET 4.5 read-only collection classes to AV1800 “Consider using Any() to determine whether an IEnumerable<T> is empty”. 
  • Added a statement to AV2207 “Don’t hardcode strings that change based on the deployment” that deployment-specific settings should be in the application configuration files rather than hard-coded or in a custom configuration file.
  • Added a remark to AV2400 “Use a common layout” not to interweave the from expressions with where conditions.

And what did I add?
The following guidelines have been added, of which, for obviously reasons, most are related to C# 5.0.

  • Added AV1137 "Define parameters as specific as possible" to prevent people from passing in entire objects even though a method might only need a specific property’s value.
  • Added AV1215 "Properly handle exceptions in asynchronous code" to explain the differences between exceptions raised in Actions and await blocks.
  • Added AV1523 "Initialize each variable on a separate line" to prevent some ugly code.
  • Added AV1739 "Use an underscore for irrelevant lamba parameters" as suggested by James Lanng.
  • Added AV1755 "Postfix asynchronous methods with Async of TaskAsync"
  • Added AV1820 "Only use async for low-impact long-running activities"
  • Added AV1825 "Prefer Task.Run for CPU intensive activities"
  • Added AV1830 "Beware of mixing up await/async with Task.Wait"
  • Added AV1835 "Beware of async/await deadlocks in single-threaded environments"

“But wait, didn’t you remove anything?”
Of course I did! Why do you think the number of pages went from 31 to 27? Well, yes, reducing line-spacing was part of that, but I actually did remove some guidelines.

  • Removed AV1120 "Use a public static readonly field to define predefined value objects " since I think it is not that important and not used very often.
  • Removed AV1245 “Don’t add extension methods to the same namespace as the extended class” because I think it is pretty farfetched if you create a class in a .NET namespace.
  • Removed AV1526 “Use an enumeration instead of a list of strings if the list of values is finite” since enumerations are so common these days, I hope nobody thinks of an alternative solution.
  • Merged AV1546 “Prefer conditional statements instead of simple if-else constructs” into AV1545 “Don’t use selection statements instead of a simple assignment or initialization”.
  • Removed AV1580 “Consider abstracting an external dependency or 3rd party component” because its essence is already covered by other guidelines and the introduction discussing SOLID principles.  
  • Removed AV2211 “Avoid suppressing specific compiler warnings” since I wonder how many developers even know how to suppress compiler warnings.
  • Removed AV2315 “Don’t use /* */ for comments” since we want to avoid inline comments anyhow.

You can download the PDFs of the document itself, the cheat sheet, the Visual Studio 2010/2012 Code Analysis rule sets, and the ReSharper 6/7 Code Analysis settings from the download page on the CodePlex landing page.

And don’t forget! If you have any feedback, additions or any remarks, contact me through Twitter or email.

Monday, November 05, 2012

Looking back at Build 2012

A question which was asked many times during the week was whether or not this trip to Build 2012 in Redmond was worth the time and money. image

Even after four days of raw content, there is no short answer here. As Dennis Vroegop clearly illustrated, the organization was definitely not up to the task just yet. The big problem is that I was expecting to visit a conference in the style of the Professional Developers Conference (which it clearly wasn't). Since Build is organized by the Windows division I should have known that they would primarily focus on Windows 8 and Windows Phone 8. On the other, the session list wasn't disclosed until a day ahead, which fed my hope to learn a lot of really new stuff. Many attendees I spoke to had the exact same thing.

On the other hand, we did receive 1200 USD worth of gadgets, and me being there give me a myriad of opportunities to network with other people in the community. The time in Redmond also kept me away from the daily challenges of my current project which allowed me the necessary peace to actually dig a bit deeper into the content. Granted, I won't go home with the mind-blowing ideas and insights such as those you get after visiting a QCon or the Norwegian Developers Conference. But at least Microsoft managed to motivate me to start the Boiling Point RT project, a revival of the Silverlight Cookbook for Windows 8.

Although Windows 8 is a major improvement over Windows 7 (just read the Building Windows 8 blog post series if you don’t believe me), but I’ve always had some doubts about the added value of the new Windows Store on an ordinary desktop PC. But this all changed after a week of using my newly acquired Surface RT. Windows 8 on a tablet is absolutely awesome. Almost everybody who I showed the device to was genuinely impressed with the sleek design, the operating system and some of the better apps. The same can be said about the Lumia 920. I really liked my Lumia 800 and found Windows Phone 7 a major improvement over Android. But I’ve always felt that WP7 was a bit limited on the customization level and lacked some decent apps. For instance, WhatsApp and Facebook were painfully slow. But this all changed with the combination of Windows Phone 8 and the Lumia 920. And the fact of the matter is that I would never have know this if I hadn’t been there.

But the question remains if it was really worth the time and money? For me it did, but that's mainly because the content was not the most important aspect for me. There were so many opportunities for meeting new people, extending my social network, and having in-depth discussions with other experienced developers, that alone makes it worth the trouble. However, it is questionable whether I will visit another Build if I get the choice. I’ll probably choose a more advanced conference such as QCon. On the other hand, maybe Microsoft will improve on itself next year or reintroduce the PDC. You’ll never know….

Sunday, November 04, 2012

Build Day 4: WP8, Line-of-Business, Web Essentials and lots of laughs

Here we are at the fourth and last day of Microsoft Build 2012. That so many people showed up at the first session is quite surprising considering the attendee party that went on until midnight in downtown Seattle. It was a typical attendee party; free food and drinks and live music. Since being amongst 2000 dudes is not our something we enjoy a lot, after grabbing something to eat, Jonne and I bailed out and took a cab to Queen Anne's to enjoy a few drinks at Peso’s.

Anyway, this first session was supposed to be a deep-dive on Windows Phone 8 internals. Although we never actual submerged, it was interesting to learn what they did to significantly decrease the start-up time of apps. And it shows, even painstakingly slow apps like FaceBook and WhatsApp start within a fraction of a second on our Lumia 920. I particularly like the way they employ the cloud to create optimized assemblies from the ones we submit through the App store. And did you know WP8 is still largely build on top of Silverlight? In fact, this was probably the only reference to Silverlight at all.

I have to mention one big issue with this conference though….Indian speakers. I would expect that Microsoft would at least make sure that all their speakers are experienced, trained and….understandable. I have nothing against Indian speakers, but guys, at least try to pronounce the things the way they should be. Looking at the Build twitter stream proved that I was not the only one suffering from this.

With another of those annoying bus trips done, we moved to a line-of-business talk with a huge line of people waiting to get in. Dennis Vroegop already shared his opinions about the transportation problem, so I won’t have to. Fortunately a majority of the Dutch community was part of this line, so that solved my problem a bit. The room was packed, even so that they decided to move the entire audience to another room just before the talk started. The talk was about building LOB apps, but spend the majority of its slot on synchronizing the app database (using a modified version of SQLite) using a customized version of the now deprecated Sync framework. The tooling look quite impressive and will become available soon.

I then went to a small meet up organized by Elizabeth Ayer from RedGate to talk about open-source projects. To my surprise Phil Haack, the author of NuGet a big catalyst for my Fluent Assertions project, also showed up as well as fellow Developer Developer Developer speaker Dave Evans. We had an interesting conversation on how companies can and should sponsor OSS developers. We didn't actually agree whether this should be done in the form of money or extra time. Money wouldn’t solve the problem of lack of time, so in my opinion, I would prefer some dedicated time. We also talked about the future of .NET, about Git and about Scott Guthrie's influence on getting a lot of Microsoft's products open-sourced. The hour passed by too quickly, because me and Elizabeth felt like we could have continued for hours.

The third session I attended was led by Mads Kristensen of the ASP.NET development team and covered the new features of the Fall Update of ASP.NET introduced. I've heard and seen most of it already throughout the other sessions. Nevertheless, the most noticeable part of his talk was the demonstration of Web Essentials 2012, a small add-on for Visual Studio 2012 that introduces a shipload of little HTML and JavaScript options. I'll most definitely going to install that little gem as soon as I get back to work.

Fortunately, in all their wisdom, the conference organizers did manage to schedule the perfect session for concluding this conference. Scott Hanselman and John Galloway took stage and managed to give the most entertaining (and still interesting) session of the entire conference. We got to play an on-line space game hosted using SignalR and watched how Scott completely bypassed the session's script, thereby utterly confusing his co-host Josh. All in all a brilliant session that you should most definitely watch.

By the way, the party was next to the Space Needle, so check out this night shot made with our new Lumia 920. Neat, isn't it?

WP_20121101_017

Friday, November 02, 2012

Build Day 3: ASP.NET MVC, TypeScript, SignalR and Node.Js

So at this 3rd day here at Microsoft Build 2012, I'm actually getting lucky. Three great sessions in a row is obviously not something I've seen before. Hey, maybe I'll get to see four great sessions tomorrow. Anyway, with some of the technical debt from last night's Beerfest and a Halloween party in Bellevue, I managed to attend most of Scott Hanselman's session. Regardless of whether the content was new or not, each of his sessions are pure entertainment.

But the highlight of the day is most definitely the TypeScript talk by technical fellow Anders Hejlsberg. It's ironic to consider that the guy that is practically the embodiment of C# is now passionately selling JavaScript. But, all things equal, he managed to fully and utterly convince me. Those existing blog posts simply don't do justice to the power of TypeScript as was demonstrated in his (recorded) session. I think it's one of the best things since C#.

Apart from the content, a conference on this scale is an excellent opportunity to meet new people and enlarge your community network. As of today, my community even includes people from Romania. I also met the guy behind the SilverlightCream and WindowsDevNews. Since I don't blog about Silverlight anymore, he kindly reminded me of his renewed focus on anything Windows 8. Just in time to submit my plans for a Windows Store Cookbook…

I never really looked at SignalR before, so a level 300 session is quite welcome, especially if it is performed by two dudes that manage to keep the talk light and humorous. SignalR is pretty cool if you want to add some simple asynchronous communication between multiple browser windows, even if you use different browsers. It feels much more elegant than using DOM navigation to hack yourself from one window to another. And the best of this all is the fact that SignalR is a Microsoft supported open-source product with a really bright future.

In the remainder of the day I wandered from one session to the other, just to find something that interests me. One of them had a memorable intro that showed the Commodore 64 emulator running an infinite Basic loop. But that session was for the most part repeating the TypeScript introduction earlier that day. Looking at the large number of people leaving and entering the session, once again reinforced my suspicion that more people were looking for some decent content.

Well, at least we had the attendee party in downtown Seattle to look forward to.

Thursday, November 01, 2012

Build Day 2: Azure, JavaScript and even more XAML and Windows Phone

Because day 2 of the Build conference wasn't any different, it seems that I must learn to accept that a maximum of two good sessions per day is going to be the standard. Fortunately the keynote was top notch with both Scott Hanselman and Scott Guthrie taking stage. They showed some of the power the Windows Azure platform provides these days. It really feels like that every time I check the Azure website they've added another shipload of features. Especially the integration between the services is something that really shines. And did I already mention how I love the look-and-feel of the Azure management portal?

One other cool thing that happened is that Microsoft announced that the Team Foundation Service is now in production. It will be a free service for teams up to 5 developers…forever. Since this is something our company has been looking forward to for a while now, I was a bit disappointed that the pricing is still to be announced. In fact, the landing page for this service states that this will not be announced until the beginning of 2013. Bummer….

After bailing out from an extremely boring XAML session I happened to run into a JavaScript session led by Amanda Silver, one of the rare female speakers at this conference. And boy, she knew what she was talking about. I'm not yet an JavaScript expert, but I was blown away hoe much one construct can make a difference compare to another performance wise. It's incredible to learn how Microsoft managed to optimize the way the IE10 JavaScript engine works internally. If you have ever attended an in-depth session on LINQ providers by Bart de Smet or a talk by Eric Meijer on the duality of IQuerable, you know what I mean. I'm in no way qualified for sharing some of her content here, so make sure you check out the slides.

Regardless of where you are, you always run into Dutch people somewhere somehow. So during lunch we ran into some 'colleagues' from a competitor and ended up discussing Event Sourcing and synchronization challenges when building large scale systems. Similarly, I was also recognized by some people which I only know through Twitter. It definitely feels a bit awkward if you don't recognize somebody, at least, not until you get to know their Twitter IDs….

The two others sessions were both about apps again. The one hosted by Chris Anderson clearly out-leveled most other sessions even though the content wasn't particularly new. As I said yesterday, it seems as if the primary audience is developers who haven't been paying a lot of attention the last year. Nonetheless, Chris once again illustrated how easy it is to integrate the search charm into your Windows Store app. I can highly recommend viewing the recording. The other one was hosted by a British chap and dealt mostly with the (powerful) combination of Azure Mobile Services and WP8 devices. It’s ridiculously easy to connect a WP device with an Azure backend without the need to build your own server. Once gain proof Microsoft wants people to start building apps (hence the free Surface and Lumina 920). What did disturb me (and I did knew about this upfront) is the fact that you are supposed to tweak the Azure services using JavaScript. Definitely not something I'm looking forward to.

image

Talking about that Surface, it's a remarkable device that managed to completely replace my Acer Aspire that I've been bringing to conferences and events. In fact, I've written this blog post using OneNote MX, the Windows Store equivalent for Microsoft OneNote but optimized for touch. The only thing I had to do on my laptop is posting the blog using Windows Live Writer. It will just be a matter of time before we'll get a decent blogging app…. and a Twitter app, and a Facebook app, and…but that's an other story…

Wednesday, October 31, 2012

Build Day 1: Surface, WP8, TFS, Windows Design Guidelines

Day 1 of Microsoft Build was in some way disappointing and at the same time exhilarating. To be honest, I was expecting to be updated on the new stuff Microsoft plans for the near future. The fact that the session list was not disclosed until a day ahead also helped reinforce that expectation. But instead, we got lots and lots of sessions on building apps for Windows 8 and Windows Phone 8. Maybe my expectations on Build are clouded with my experiences attending the Professional Developers Conference in 2008 and 2009. Maybe another problem is that Build is paid by the Windows Division whereas the PDC was mostly organized by the Development Division (and we all know how Steven and Somas get along together). On the other hand, Build 2012 did deliver on the hardware side by giving each and every attendee a Surface RT as well as Nokia's flagship, the Lumia 920. That's not something anybody dared dreaming off. And yes, we all know we're going to be Microsoft's marketing tool for the next months, but it's still incredibly cool.

clip_image001

Anyway, I started the day listening to Buck Hodges, product manager of the TFS suite, talking about how they employ Scrum within their department. I was happy to hear that they approach product development similarly to how my current client is doing it. Their cadence is to plan 3 week sprints concluded with a one week verification before they release to production. They rely heavily on automated testing, but at the same time balance 6 developers with 5 testers. Granted, their teams are a bit on the big side (5 + 6 + 1 or 2 product managers), it clearly shows how much they value quality. Buck also shared how they deal with branches. In general they try to avoid feature branches (which resonates well with Martin Fowler's opinions on that), and most changes are directly committed to the main branch. The only exception to this is when commits are too disruptive. As an example of this, Buck mentioned the data access changes required to complete the transition from the relatively expensive SQL Azure to Azure Table Storage.

The other session that was worth my time was dealing with web standards. It was a good reminder of how standards compliance works, what browsers are being used currently, and how libraries like Modernizr can help you with that. The highlight of the session was the reference to browserstack.com, a website dedicated to testing your website against a myriad of browsers. I also attended some sessions on the user interface and interaction design of Windows 8, but most of what was told is already common knowledge. Only people who have been living in a cage for the last year (one deep enough to not receive any Wi-Fi signals), may have heard something new. Let's hope the sessions planned for day 2 are a bit better.

Planning the Windows 8 Cookbook

I'm currently at Microsoft's Build conference and we're all receiving a Surface RT tablet. That means it's a great moment to talk about my plans for the Windows 8 Cookbook. I know, I know, it's a cheesy name so just be aware that I'm open to better suggestions. Since Silverlight is mostly dead, I've decided to revive the Silverlight Cookbook by rebuilding it as a Windows Store app instead. This time I'm also going to get some help on the UI design so hopefully it will finally get a decent looking front-end.

Another thing I'm considering is to host the entire project on GitHub. I've already build up some experience with Git on CodePlex as the result of a recent conversion of my Fluent Assertions project, but I'd like to get to know how that compares to the GitHub experience. Whether or not it's going to be CodePlex or GitHub, I will be accepting pull requests. And if you are interested in contributing a bit more directly, I'm also looking forward to people who want to help me build the project.

To give you some more context on the technical platform behind the cookbook, here are some of the things I'd like to use:

The Cookbook is supposed to demonstrate how to build line-of-business applications based on the Windows Store platform. That means it's going to use some design decisions that are completely overkill for this particular example, but should be very relevant for real-life projects.

One thing on which I'm still in doubt of is the data access strategy. I'm well aware that Event Sourcing shouldn't be used without careful considering. But the fact of the matter is that I'm doing a project right now where we wanted to use RavenDB, but decided to go for Event Sourcing using a traditional database instead. These are the four choices I have in mind.

Aggregate storage with…

  1. SQL Server using NHibernate
  2. RavenDB for storing the aggregates and using its Lucene-based indexing engine for querying

…or Event Sourcing using Jonathan Oliver's EventStore combined with Lokad.CQRS's aggregate design

  1. Using SQL Server as its backing store as well as a query store.
  2. Using RavenDB for storing both the events and the query models, optionally adding faceted search options provided by Lucene.

I have to admit, this seems to be quite an ambitious project to be doing during free evenings. But I'll be reusing a lot of code from the Silverlight Cookbook, so that should save some time.

Let me know what you think of the direction I plan go in. You can email me, tweet me, or spend a few minutes of your valuable to fill in this survey.

A weekend in Emerald City

This week is Microsoft Build 2012. For those who don’t know what that is, it’s Microsoft largest and most important annual event for sharing the future of the company’s plans around Windows, Windows Phone and their development platforms. Since with most trips to the US, it’s usually cheaper to take a flight on a Saturday than one on Monday, even if you consider the additional lodging costs. Since the area around Microsoft’s campus in Redmond isn't particularly exciting, me and colleague Jonne Kats decided to spend the first few days of this week long trip in downtown Seattle.

WP_000017

After a 2.5 hour delay caused by a allegedly flat tire (that ended up being a sensor error after all), we arrived at Seatac Airport at around 14:30 local. We then had to pick up our ride for the week, a 2012 Chevrolet Malibu LT. Not a particular nice car, but it’s considered a full-size sedan so that’s more than enough to carry our luggage. The car didn’t come with a GPS, but to our surprise Nokia Drive did its job better than expected. Just imagine how glad I was that I loaded the maps of state Washington prior to our trip. And since Nokia Drive 3.0 doesn’t require a live internet connection anymore, this didn’t cost us anything.

WP_000030

That first night we decided to visit Capitol Hill to see what Halloween in Seattle is about. Having visited California a few times, I was surprised to see how few people were dressed up over here. It must have been the pouring rain, or the cold. We decided to take a quick bite at a Mexican restaurant we ran into because somebody noticed our indecisiveness. The fun part started when I ordered a Mojito to compensate for the lack of sleep. As you may know, in the US you cannot buy alcohol if you’re under 21. Now I’ve been called at for having a baby face….but… that was 20 years ago and I’m 39 now, Initially they refused to serve us that hard needed Mojito. It took us quite a lot of negotiation to finally get a single round. Anyway, after diner we tried to enter a small Halloween-styled bar. But again we were kept out because we didn’t bring our passport. This all feels a bit hypocrite which somebody pointy stated on Facebook: you get a free gun with a new bank account, but you cannot get a decent drink without a passport!

WP_000020

The next morning, after a good night sleep, we were happily surprised with a clear blue sky. So after a quick breakfast at the local Starbucks, we planned a small road trip through the greater area of Seattle. Oh, and as a side note, where we thought to have seen Starbucks’ at virtually every corner just the night before, now we had to really search to find one. Anyway, we took the i90 to North Bend to visit one of those Seattle outlet factories and then to another one in Marysville just to enjoy the scenery of Washington in the Autumn.

WP_000010

Obviously we grabbed a genuine home-made burger along the trip, thereby carefully avoiding any fast-food chains. And now that I mention it, the US is really a country of opposites. We regularly noticed billboards that stated that 1 of 6 US citizens is in hunger. But at the same time you’ll find these food centers with shops like McDonalds, Burger Kings, Denny’s, Taco Bells and Subways virtually after few miles. In fact, it is easier to get a burger than to find a gas station. How can anybody be hungry here?

After about 250 km of driving we went back to the hotel and prepared to get some dinner somewhere. With our passports in our back pockets we took a cab to the waterfront to see if there was anything to do. Fortunately our cab driver understood our intentions and proposed to bring us to Belltown, an area known for great restaurants, bars, etc. But…..it was mostly abandoned. We selected a random Sushi bar and actually enjoyed a great mixture of Japanese and Hawaiian cuisine. But when a group of large sized American geeks started up the Karaoke (granted, they could definitely sing), we left to visit a large bar across the street to grab a beer. The girl behind the bar explained to us that just the evening before, that bar was packed with 1300 people whereas now it contained about 15. Go figure….

WP_000011

As suggested by the bartender, we took another cab to Queen Anne’s, presumably another place were you’ll find a lively crowd……..NOT. Nevertheless, we hooked up with a group of friends and spend the remainder of the evening discussing the economy, politics and the apparent uptightness of Seattle citizens. We had a lot of fun, regardless of the relative quietness of that evening. Bedtime was a lot later than planned.

The Monday concluded the free time prior to the event in which we visited Pike Place Market and then traveled to the north to explore the area of Mount Rainier. We did visit some shops but then decided to drive to Redmond to preregister for the conference.  To avoid traffic, we took an alternative road from Bellevue to Redmond and enjoyed the view.

WP_000031

Again, I can highly recommend renting a car when you are in the Seattle area, even if you need to stay downtown. You miss so much of the great environment if you rely on public transport only. All in all, not a bad start for this exciting week in the US.

Monday, October 08, 2012

Fluent Assertions 2.0 is out of the beta phase

After six weeks of beta testing, it is time to remove the beta mark from Fluent Assertions 2.0. Since the beta was released, we fixed several little bugs that you won’t notice, but the original release notes still apply. Release 2.0 adds a lot of new features and improvements, most noticeably the new syntax for comparing complex object graphs and support for .NET 4.5, Windows 8 Apps and Windows Phone 7.5 (Mango). You can get a copy of the zip through the CodePlex download page, but I suspect most of you will use the NuGet package instead.

For those who’d like to provide contributions, make note that we are now on a GIT repository, so we will accept your pull requests. And as usual, for questions, remarks or suggestions, you can use the Discussions page, StackOverflow, or you can contact me directly by email or Twitter.

Monday, September 03, 2012

Asserting object graph equivalence using Fluent Assertions 2.0

As promised in the announcement about version 2.0, I will finally explain the details behind the new extension methods for asserting that two object graphs are equivalent. For the record, these new extension methods are going to supersede the old ShouldHave() method somewhere in a next major version. Internally the old methods are already using the new comparison engine, but new functionality will only be available through the new methods.

Selecting the right properties
Consider the class Order and its wire-transfer equivalent OrderDto (a so-called DTO). Suppose also that an order has one or more Products and an associated Customer. Coincidentally, the OrderDto will have one or more ProductDtos and a corresponding CustomerDto. Now if you want to make sure that all the properties of all the objects in the OrderDto object graph match the equally named properties of the Order object graph, you can do this.

orderDto.ShouldBeEquivalentTo(order);

In contrast to the ShouldHave() extension method, the comparison is recursive by default and all properties of the OrderDto must be available on the Order. If not, an exception is thrown. You can override this behavior in different ways. For instance, you may only want to include the properties both object graphs have:

orderDto.ShouldBeEquivalentTo(order, options =>
    options.ExcludingMissingProperties());

You can also exclude certain (potentially deeply nested) properties using the Excluding() method.

orderDto.ShouldBeEquivalentTo(order, options => 
    options.Excluding(o => o.Customer.Name));

Obviously, Excluding() and ExcludingMissingProperties() can be combined. Maybe farfetched, but you may even decide to exclude a property on a particular nested object by its index.

orderDto.ShouldBeEquivalentTo(order, options =>
    options.Excluding(o => o.Products[1].Status));

The Excluding() method on the options object also takes a lambda expression that offers a bit more flexibility for deciding what property to include.

orderDto.ShouldBeEquivalentTo(order, options => options
    .Excluding(ctx => ctx.PropertyPath == "Level.Level.Text"));

This expression has access to the property path, the property info and the subject’s run-time and compile-time type. You could also take a different approach and explicitly tell FA which properties to include.

orderDto.ShouldBeEquivalentTo(order, options => options
    .Including(o => o.OrderNumber)
    .Including(o => o.Date));

Overriding and collections
In addition to influencing the properties that are including in the comparison, you can also override the actual assertion operation that is executed on a particular property.

orderDto.ShouldBeEquivalentTo(order, options => options
    .Using<DateTime>(ctx => ctx.Date.Should().BeCloseTo(ctx.Date, 1000))
    .When(info => info.PropertyPath.EndsWith("Date")));

If you want to do this for all properties of a certain type, you can shorten the above call like this.

orderDto.ShouldBeEquivalentTo(order, options => options
    .Using<DateTime>(ctx => ctx.Date.Should().BeCloseTo(ctx.Date, 1000))
    .WhenTypeIs<DateTime>();

The original ShouldHave() extension method does support collections now, but it doesn’t allow you to influence the comparison based on the actual collection type. The new extension method ShouldAllBeEquivalentTo() does support that so you can now take the 2nd example from the post and apply it on a collection of OrderDtos.

orderDtos.ShouldAllBeEquivalentTo(orders, options =>   
    options.Excluding(o => o.Customer.Name));

Extensibility
Internally the comparison process consists of three phases.

  1. Select the properties of the subject object to include in the comparison.
  2. Find a matching property on the expectation object and decide what to do if it can’t find any.
  3. Select the appropriate assertion method for the property’s type and execute it.
Each of these phases is executed by one or more implementations of ISelectionRule, IMatchingRule and IAssertionRule that are maintained by the EquivalencyAssertionOptions. The ExcludePropertyByPredicateSelectionRule for example, is added to the collection of selection rules when you use the Excluding(property expression) method on the options parameter of ShouldBeEquivalentTo(). Even the Using().When() construct in the previous section is doing nothing more than inserting an AssertionRule<TSubject> in to the list of assertion rules. Creating your own rule is quite straightforward. 
  1. Choose the appropriate phase that the rule should influence
  2. Select the corresponding interface
  3. Create a class that implements this interface
  4. Add it to the ShouldBeEquivalentTo() call using the Using() method on the options parameters.
    subject.ShouldBeEquivalentTo(expected, options => options
        .Using(new ExcludeForeignKeysSelectionRule()))

That’s it for now. As usual, for questions, remarks or suggestions, you can use the Discussions page, StackOverflow, or you can contact me directly by email or Twitter.

Off topic: Although we’re still on CodePlex, the source code of Fluent Assertions is now stored in a Git repository. That should make it a whole lot easier for contributors to fork the code, write a nice improvement, and send us a pull request.

Friday, August 31, 2012

Slides and demo code for my SpecFlow/WaTiN talk

Yesterday I did a 2-hour talk on getting the most out of UI automation, particularly using SpecFlow and WaTiN. You can find the slides down here and the demo code at GitHub.



Off Topic: If you're looking for a change in your career, know that we're still looking for Dutch-speaking new developers with all levels of experience. If that doesn't suit you, my client (in The Hague) is also looking for .NET developers for a permanent position. Let me know if you need more info.

Tuesday, August 28, 2012

The Best Articles and Blog Posts of August 2012

Here are some of the highlights of the blog posts, articles and whitepapers I’ve read this month.

Sunday, August 26, 2012

Breaking with the past (or…Fluent Assertions 2.0 is in beta)

After many months of development, in particular during in evenings after work and in the weekends, we’re proud to present the first (and hopefully the only) beta of Fluent Assertions 2.0. Together with my good friend and coworker Martin Opdam, and supported by noticeable contributors like Oren Novotny and Ian Obermiller, we managed to introduce a shipload of new features.
 


For instance, Oren worked on the foundations for supporting the new Windows 8 Metro-style apps, whereas Ian created the initial Windows Phone 7.5 version. Martin added support for .NET 4.5, added quite a few new variations and overloads to the existing assertions and also fixed a lot of the reported bugs. I myself introduced a completely new extensible API for comparing two objects graphs for equivalence. As the original founder of this project, I also took charge of safeguarding the overall quality and consistency.

And now that I mention it, after a week of debugging I almost decided to drop Windows Phone support altogether. I was suffering from two really persistent ReflectionTypeLoadExceptions and MissingMethodExceptions. Since I’ve started developing on the .NET platform in 2001, I’ve run into some pretty weird issues, but this was a whole new league for me (read the StackOverflow discussion to learn a bit more about this issue). Fortunately Geert van Horrik pointed me at a blog post he wrote a while back that explained Windows Phone’s lack of support for co- and contravariance. And indeed, that was exactly the problem I was facing all the time.

So in addition to support for the aforementioned .NET flavors and support for MBUnit and the Gallio Automation Platform, what else did we add?

What's new for collections
  • Added (Not)BeInAscendingOrder(), (Not)BeInDescendingOrder(), IntersectWith(otherCollection) and NotIntersectWith(otherCollection).
  • ContainInOrder() got an overload that takes a params object[] argument rather than an IEnumerable in case you don't care about the reason.
  • Added ContainSingle() that asserts there is only a single element in the collection that matches the specified lambda.
  • Added an overload to Equal() that takes a lambda that is used for checking the equality of two collections without relying on the type’s Equals() method. Consider for instance two collections that contain some kind of domain entity persisted to a database and then reloaded. Since the actual object instance is different, if you want to make sure a particular property was properly persisted, you usually do something like this:
    persistedCustomers.Select(c => c.Name).Should().Equal(customers.Select(c => c.Name);
    With this new overload, you can rewrite it into:
    persistedCustomers.Should().Equal(customers, c => c.Name);
  • Fixed a bug that occurred when two collections are compared for equality but the collection contains nulls.

What's new for strings
  • When strings differ in length, it will report the expected and actual lengths as part of the error messages.
  • An ArgumentOutOfRangeException was thrown when asserting that a string started with a specific string and the first string was shorter than the expected string.

What's new for numbers
  • Added support for using Be() on nullable numeric types.
  • Added BeOneOf() to assert that a value matches one of the provided values.
  • Added support for (nullable) decimals
  • BePositive() and BeNegative() now also work for floats and doubles.

What's new for dates and times
  • Added NotBe(). Also added BeOneOf() to verify that the value matches one of the provided values.  
  • Added BeCloseTo() to assert that a date/time is within a specified number of milliseconds from another date/time value. This can be particularly useful if your database truncates date/time values.
  • If a date/time value has non-zero milliseconds then that will be displayed in the error messages .

What's new for comparing object graphs
I’ll dedicate a separate blog post on the new object.ShouldBeEquivalentTo(object) and collection.ShouldAllBeEquivalentTo(collection), but the existing API based on the object.ShouldHave() has benefited from the internal redesign as well.
  • You can now apply the property equality comparisons to entire collections of objects. It doesn't matter what kind of collection type you use, as long as it contains the same number of objects, and the object’s properties match.
  • The error message now includes the index of the mismatching object.
  • An exception was thrown when comparing the properties of an object and one of them causes a cyclic reference. You can now alter that behavior by passing in a value from the CyclicReferenceHandling enum into the IncludingNestedObjects() method.
  • Added support for references to an interface rather than concrete types. You can find an example of that at the corresponding feature request page.
  • Added support for comparing two anonymous types using SharedProperties().
  • Fixed a bug that caused an exception to be thrown for write-only properties. They are now ignored.
  • Fixed a stack overflow exception when formatting an object graph that contains a static property with a cyclic reference.
  • Fixed an exception that was thrown when formatting an object graph and one of the properties throws.
  • The name of a date/time property was not included in the error message when AllProperties() failed on that property

What's new for types
  • Added the static AllTypes class with a static method From(Assembly assembly) as a wrapper around the Types extension method on Assembly. This allows for a more fluent syntax like
    AllTypes.From(assembly)
      .ThatAreDecoratedWith<SomeAttribute>()
      .ThatImplement<ISomeInterface>()
      .ThatAreInNamespace("Internal.Main.Test");
  • Added support for asserting that the properties of an attribute have a specific value. For instance: 
    typeWithAttribute.Should()
      .BeDecoratedWith<DummyClassAttribute>(a => ((a.Name == "Unexpected") && a.IsEnabled));
What other improvements did we include 
  • Fixed an exception when asserting the equality of dictionaries that contain nulls.
  • The NuGet package will automatically add references to the System.Xml and System.Xml.Linq references.
  • Added a ShouldThrow<TException>() method for a Func<Task> to support working with async methods like this:
      Func<Task> slowFunction = async () => { await slowObject.ThrowAsync<ArgumentException>(); };
      slowFunction.ShouldThrow<InvalidOperationException>(); 
  • Improved several of the error messages related to assertions on XDocument and XElement.  
  • All overloads that took the reason and reasonargs parameters have been removed and replaced with optional parameters
  • Allowed ShouldRaisePropertyChangeFor(null) to assert that an object implemented INotifyPropertyChanged raised the changed event for all properties.

What’s new for extensibility
  • The list of IValueFormatter objects on the Formatter class can be altered to insert a custom formatter.
  • Introduced a mechanism to override the way Fluent Assertions formats objects in an error message by annotating a static method with the [ValueFormatter] attribute. If a class doesn’t override ToString(), the built-in DefaultValueFormatter will render an object graph of that object. But you can now override that using a construct like this:
    public static class CustomFormatter
    {
        [ValueFormatter]
        public static string Foo(SomeClassvalue)
        {
            return "Property = " + value.Property;
        }
    }
  • We introduced a mechanism so that the error message of custom assertion extensions can specify the {context} tag that is used to inject the property path in object graph comparisons. For instance, in the date/time assertions, this is used to display date and time. But when this assertion is used as part of a recursive object graph comparison, it will display the property path instead.
    Execute.Verification
        .ForCondition(Subject.Value == expected)
        .BecauseOf(reason, reasonArgs)
        .FailWith("Expected {context:date and time} to be {0}{reason}, but found {1}.", expected, subject.Value);
  • The NuGet package is now based on NuGet 2.0.

Breaking changes
Since we decided to bump up the version from 1.7.1 to 2.0 and we’ve already told you that we comply to Semantic Versioning, you can expect some breaking changes in this release.
  • In order to ensure that all extension methods are always available through the FluentAssertions namespace, we had to get rid of the FluentAssertions.Assertions namespace. Just use a global search-replace to remove all those usage statements.  
  • Many of the assertion classes have moved into dedicated namespaces. You might have to fix any code that inherits from those classes.
  • Remove the obsolete Verify() methods from the Verification class

So what’s next
To get started, get the NuGet package from inside Visual Studio (just make sure you include pre-release versions), or get the ZIP through the CodePlex download page. If you run into issues, I would prefer that you ping me directly on Twitter before you file an issue on CodePlex’s Issue Tracker. By the way, we use the #fluentassertions tag on Twitter. For questions, remarks or suggestions, you can use the Discussions page, StackOverflow, or you can contact me directly by email or Twitter.

Off topic: Although we’re still on CodePlex, the source code of Fluent Assertions is now stored in a Git repository. That should make it a whole lot easier for contributors to fork the code, write a nice improvement, and send us a pull request.

Monday, July 30, 2012

Quick Review of The Cucumber Book from a SpecFlow perspective

This week I completed reading a new book titled The Cucumber Book: Behaviour-Driven Development for Testers and Developers by Matt Wynne and Aslak Hellesoy. Aslak is the founder of the Cucumber project (which is what SpecFlow for .NET is based on), and Matt is one of its most active developers. The 328-page book is only 20 USD if you get it through The Pragmatic Bookshelf and worth the money, even if you're an experienced SpecFlow developer/tester.

clip_image001

The code examples are written in Ruby, but even without any prior knowledge of Ruby, I managed to get through them quite easily. (Off-topic: It's not a language I see myself coding in anytime soon, so I must be a C-language addict).

Anyway, the first 6 chapters (Part I) are awesome. Not only do they provide a decent introduction to the concepts behind Cucumber and a detailed break down of the Gherkin language, it also provides numerous tips and tricks that should prevent you from making your efforts gone bad. Just as you can go bad with practices like TDD, there's a whole lot you can do wrong when dealing with automation scenarios based on the Gherkin language. Even after reading the Secret Ninja Cucumber Scrolls and everything there is to read on SpecFlow, I learned some valuable new lessons that sure are going to improve the work I'm doing right now.

Chapters 7-10 (Part II) are taking a deep-dive in implementing the Step Definitions using Ruby. Since I don't care about the Ruby details, I mostly browsed through these pages looking for hidden tips and tricks. If you are a .NET developer like me, I would do the same. But just make sure you read all the side-notes (the ones with a bluish background). They contain some valuable best practices.

Again, if you're a .NET developers, you can skip chapters 11, 14 to 16 and the appendixes since they are too specific to the Cucumber tool and the Ruby language. But do try to read chapters 12 (Testing a REST Service) and 13 (Adding Tests to a Legacy Application).

You might wonder why I still believe the 20 dollars are worth the money after I told you to skip so much of the book's contents. It just that those first 100 pages plus the many best practices in the remainder of it really make up for the rest of the book. Since I'll be talking about SpecFlow and WaTiN at the Dutch .NET User Group meeting on August 30st, I have been looking for some decent advice on writing proper Features and Scenarios for a while. The book delivered. Period.
For completeness, here’s the table of the contents.
  1. Why Cucumber?
  2. First Taste
  3. Gherkin Basics
  4. Step Definitions: From the Outside
  5. Expressive Scenarios
  6. When Cucumbers Go Bad
  7. Step Definitions: On the Inside
  8. Support Code
  9. Dealing with Message Queues and Asynchronous Components
  10. Databases
  11. The Cucumber Command-Line Interface
  12. Testing a REST Web Service
  13. Adding Tests to a Legacy Application
  14. Bootstrapping Rails
  15. Using Capybara to Test Ajax Web Applications
  16. Testing Command Line Applications with Aruba
PS. Did you know that SpecFlow 1.9 is eminent? Check out the preliminary release notes.

Thursday, July 26, 2012

Noticeable quotes from QCon New York

Just to be clear, I didn’t actually attend QCon New York this year. But after the experience of attending QCon San Francisco in 2010, I never forget the many great quotes you’ll find on Twitter. This time was no different.
As you can expect from somebody like Michael Feathers, he made some great quotes in his talk on Patterns of Software Change.
  • Architecture - the part of the system that you can not replace without having a different system
  • "Over-engineering = weighting a possible future too highly in design."
  • “Code Turbulance”, a name for frequently changed code
  • Anytime you manage by the numbers, instead of actually (God forbid) looking at the code a way will be found to game the numbers”, in a discussion on the uselessness of using only code metrics for judging the quality of your code base.
Looking forward to QCon San Francisco in November…

Friday, July 20, 2012

Required Reading Material for July 2012

Since I was already collecting the better articles that I read during the month for sharing with my colleagues and client’s coworkers, I might just as well share them here. Have fun reading them.

Virtual Panel: Code-to-Test Ratios, TDD and BDD 
A great discussion by the authorities on TDD, BDD and Specification By Example.

Agile Undercover: When Customers don’t Collaborate 
Contains best practices for dealing with the reality issues of a Scrum project.

What's Upcoming in jQuery 1.8, 1.9 and 2.0, and the Removal of IE6/7/8 Support.
A summary of important changes in the next versions of jQuery.

ReSharper 7: What’s Inside.
Even if you are already running the beta, it’s still worth a read.

Eventual consistency, CQRS and interaction design
An important aspect of using Event Sourcing is the Eventual Consistency aspect. This article explains that in more detail and how it affects the perception of the end-user.

The Turkish İ Problem and Why You Should Care
Illustrates the difficulties of not properly preparing an application for supporting multiple languages.

The Art of Misdirection
As can be expected from one of the best speakers in our profession, a deep insight in the hidden cost of software developments. Incidentally covers TDD as well.

Thursday, July 19, 2012

If you write an article about TDD, make sure it is correct

I spend a majority of my private time reading articles and blog posts, having discussions on Twitter, or engaging in conversations on conferences and community events. I'm realistic enough to understand that my opinions are not necessarily the truth, so I use those opportunities to challenge my own ideas and learn about solutions I would never think of myself.

I recently read an article titled Test-Driven ASP.NET MVC that, although I respect what the author is trying to convey, implies some things that I strongly believe are incorrect or are malpractices. Normally I wouldn't bother to blog about this, but because his article is published at the online MSDN Magazine, I couldn’t resist the urge to correct some things.

  • Thoroughly understand the MVC pattern. As Martin Fowler has clearly explained in his post on GUI patterns, the view doesn't manage the presentation of models, nor does it handle interactions with the users. Both are the responsibility of the controllers. They react to keyboard, mouse (and touch) input, use that information to interact with the (domain) model and then decide what view should be used to render the result. In that sense, ASP.NET MVC is reasonably faithful to the original pattern. The only big difference is that in the original MVC pattern, the controllers were directly handling user input whereas in ASP.NET MVC the controllers merely handle HTTP POSTs, GETs and PUTs.
  • Tiers are not layers. Tiers are used to represent a physical separation whereas layers represent a logical separation. You can have all layers (e.g. presentation, service, domain and data access) hosted on a single tier if you want, or you can assign them to multiple tiers. An example of that is an ASP.NET web site (the presentation layer) hosted on a front-end web server, the service, domain and data access layers hosted on a Intranet application server, and the database hosted on a dedicated database server. The other way around doesn't work like that though. If you didn't account for layering in your architecture, it might be very difficult to deploy your system in a distributed environment.
  • Keep your Visual Studio projects to a minimum. Having many projects such as the project-per-layer suggested in the article considerably slows down compiling, but also causes the startup time of the corresponding application to increase. Loading 10 small assemblies is much slower than loading one big assembly. Jeremy D. Miller mentioned this already in this post, but Patrick Smacchia, the author of NDepend, delivered some proof of if it here. Read my original post for more guidance on splitting up projects.
  • Separate test code from production code. The author recommends separating test code from production code, a good thing obviously. In fact, I would not even dare to think of polluting the production code base with test code. It might double the size of the assemblies and considerably increase the memory footprint of the application. But as usual, it is not always possible to avoid this. We sometimes have to make a method internal and allow the test projects to access those members using an [InternalsVisibleTo] assembly-level attribute. But that's an exception. What we do more often is make certain methods protected so that we can apply the Test-Specific Subclass pattern.
  • TDD is about test-first development. The article refers to the Test-Driven Development practice a few times but never explains its essential concepts such as writing tests before writing the production code, the red-green-refactor mantra and the many benefits it offers from a design and maintenance perspective. And neither does it explain what the exact meaning of a unit in unit testing is. In fact, not a single code example shows what a unit test would look like when practicing TDD in an ASP.NET MVC application. Why then call the article Test-Driven ASP.NET MVC. This is even more surprising considering that the author is using Jeremy D. Miller's StructureMap, somebody who has been one of the most noticeable TDD advocates in the community. I wonder whether the author really understands TDD at all.
  • Use Fakes with caution. This is also amplified by his apparent nonchalant use of Visual Studio 2012's support for generating fakes from any class. If you're practicing TDD, you’ll explicitly design the interface of your API or type and think about its dependencies. IMHO, this is an essential part of the thought process involved in TDD. Using a brute-force tool like Fakes or TypeMock Isolator allows you to ignore that part of the process and just generate whatever is needed for your test. I'm not saying Fakes or TypeMock are bad products, but because of their unique capabilities compared to popular mocking frameworks like Moq, Nsubstitue or my own favorite, FakeItEasy, I'm afraid many people will follow the author's example.
  • Dependency injection is not the same as the inversion of control principle. I hate it when developers use the terms Dependency Injection and Inversion-of-Control interchangeably. They are two different things and if you don't understand that, make sure you thoroughly read the chapter on the Dependency Inversion Principle in Pablo's SOLID guidelines. Although subtlety different, Inversion-of-control is essentially about removing the direct dependencies of one class to another out of that class and providing an abstraction that that class relies on. The inversion in this principle is about moving the responsibility for hooking up the original class with a concrete implementation of that abstraction to a 3rd party, typically an IoC framework. This will improve your chances for loose coupling, better testability, and increased maintainability on the long run. Obviously you don't have to use a DI framework, but if you do it correctly you can gain a lot of benefits from it. I myself heavily rely on Autofac after having used Microsoft Unity for a few years. And remember, just like any principle or tool, use it with caution. Overusing IoC can result in systems were it is difficult to understand what happens.
  • Resolving dependencies from inside a class completely defies the ideas behind DI. Why in the world would you suggest people to use an DI framework like StructureMap and then use a static class to resolve dependencies from within the dependent class? That vaporizes the entire purpose of a DI framework. It's not for nothing that Jeremy D. Miller wrote a post on Push, Don't Pull. Even better, that's why the word injection is in Dependency Injection! That is also why the author suggest registering a fake object in his IoC container. This is clearly a design smell resulting from his apparent incorrect understanding of the IoC principle.
  • One more issue. In the discussion on namespaces and test code, the author suggested to use the name Test (singular) in the project name. Since the namespaces in projects should use the project name as their base, you end-up with the name of something that could be the name of a class. That has been a violation of the Microsoft Design Guidelines and FxCop naming rules since the inception of the .NET Framework. I usually use the name Tests, Testing or Specs for the project that holds the unit and integration tests.

Anyway, the morale of this post is that you should get your facts straight before you write an article that is going to reach so many people. And now that I think of it, why didn't somebody from the MSDN Magazine's staff check this article in the first place? I might be wrong as well, so if disagree let me know by commenting on this post or by pinging me through my twitter handle at ddoomen.

Friday, March 23, 2012

Fluent Assertions gets a bug fix release

While we are working on the next major version of Fluent Assertions, we received several smaller bug reports that we bundled in release 1.7.1.

  • Fixed a bug that occurs when two collections are compared for equality but the collection contains null.
  • Fixed a stack overflow while formatting an object graph containing static cyclic references.
  • Fixed the issue where an exception was thrown when building a failure message by dumping the values of all properties, and one of the properties throws an exception.
  • Made the handling of cyclic references when validating equality of nested properties configurable (ignore / throw exception)
  • Fixed some incorrect failure messages when comparing XML elements and attributes
  • Fixed a NullReferenceException when comparing objects that have a write-only properties
  • Fixed a potential NullReferenceException while comparing the properties of a complex graph and when a deep property contains a null object.

These days, our preferred delivery mechanism is NuGet, but you can still get a ZIP from the CodePlex landing page. Issues can be dropped on the Issue Tracker page, but we also monitor any StackOverflow tagged with fluent-assertions.

Tuesday, March 13, 2012

About the future of the Silverlight Cookbook

Since my first blog post on the Silverlight Cookbook in September 2010, I’ve invested a lot of private time in sharing my best practices on building line-of-business application in Silverlight. I shared my code on CodePlex, wrote an entire series of blog posts, and talked about the Cookbook at several events.

Times change, and although I’ve always believed (and still do) that Silverlight is a great technology for building interactive line-of-business applications, the lack of a roadmap for Silverlight is making even my clients hesitate. And yes, I did explain them about Microsoft officially supporting Silverlight 5 until 2021.

To help me make a decision about the direction of the Cookbook, I’ve started a poll in the side-bar of my blog. The important question I ask is whether I should continue with Silverlight, move towards Windows 8 Apps (in XAML/C# of course), or finally make the jump to HTML5/JavaScript. The few votes I’ve received so far tend to lean towards the latter, but I’m not willing to make that jump until more people have voted.

So let know!

Friday, January 13, 2012

Fluent Assertions 1.7.0 has been released

It has barely been more than two months ago, but the number of downloads through CodePlex and Nuget combined has exceeded 2000. Me and co-author Martin Opdam thought that to be a nice reason for releasing a new version of Fluent Assertions. This isn't a big release, but since we are following semantic versioning and we added new functionality as well as some bug fixes, an increment in the minor number is in order. Since we prefer NuGet ourselves, get the latest version through its NuGet landing page. If you prefer the old-fashioned way, get it through CodePlex. Here are the release notes.

What's New

  • Added methods for asserting that a collection of types matching a predicate have specific methods that are virtual or marked with a specific attribute.
typeof(MyController).Methods()
.ThatReturn<ActionResult>()
.ThatAreDecoratedWith<HttpPostAttribute>()
.Should()
.BeDecoratedWith<ValidateAntiForgeryTokenAttribute>(
"because all Actions with HttpPost require ValidateAntiForgeryToken");


  • Added methods for asserting XElements and Xattributes

xDocument.Should().HaveRoot("configuration");
xDocument.Should().HaveElement("settings");

xElement.Should().HaveAttribute("age", "36");
xElement.Should().HaveElement("address");

xAttribute.Should().HaveValue("Amsterdam");


  • Added support for recursively comparing the properties of nested (collection of objects ). By default it will compare all properties of the expected object graph, unless SharedProperties is used.
  • Added a fallback mechanism so that if FA cannot find any of the supported frameworks, it will fall back to using a custom AssertFailedException exception class rather than crashing.
  • Added support for ComparisonMode.StartWith and ComparisonMode.StartWithEquivalent when asserting the message of an exception.
Bug Fixes & Improvements



  • For assertions that verify against a Type, the failure message will use the AssemblyQualifiedName rather than just the name of the type.
  • Fixed a bug so that collection.Should().OnlyContain(lamba) now throws if the collection is empty. See this discussion for more details.
  • Minor fix that ignores trailing blank characters when looking for the 'because' text in the reason of an assertion.
  • Added better and deeper detection of cyclic references when recursively comparing properties or generating a string representation of a complex object graph.
  • For long strings, the error message for string.Should().StartWith() places the actual and expected strings on seperate lines. This makes it easier to find the differences.

By the way, we’ve also spent some time updating the documentation.