Wednesday, March 26, 2008

If you've been working with the .NET Framework for a while, you're hopefully already using some form of static analysis to help you catch problems with your code. One of the most well known is Microsoft's FxCop, which is now integrated as the Code Analysis feature in Visual Studio 2005 [1] and up. If you're not already using this tool, then please start because it can help you find problem areas like potential NullReferenceExceptions as well as globalization and security issues.

However, while FxCop is great at catching small problems and details, it isn't the best tool to see the big picture regarding your software. Enter NDepend by Patrick Smacchia. Chances are, you've already read Scott Hanselman's great review of NDepend a while back (or heard his podcast on static analysis with NDepend). If you haven't read it, go ahead and check it out. Scott uses NDepend to analyze dasBlog (which I'm running), so you can get the general feel for working with NDepend and what the reports look like.

I'd like to run through a few of the features of NDepend using Rhino Mocks as the target of my static analysis. Rhino Mocks is a neat example because it is only one assembly, but it is the result of an ILMerge of quite a few different libraries, so we get to see how NDepend handles this. Here is NDepend's class browser showing Rhino Mocks:

image

As you can see, it handles Rhino Mocks accurately. In fact, it almost feels like the class browser in Reflector, so that is already a plus. In fact, as you can see, the context menu supports jumping to Reflector for the selected type.

The "Who is directly using me?" option is also pretty cool and highlights the extensive use of CQL in NDepend:

image

CQL, or Code Query Language, is the centerpiece of NDepend and is how all of the analysis happens. You can think of it as SQL against IL. The massive benefit that NDepend has over FxCop IMHO is that you can create your own analysis rules in CQL instead of having to write and compile a DLL to extend FxCop (for an example of this, check out this FxCop rule that ensures that ArrayLists are List<T>s instead). Even better, NDepend provides a complete editor with intellisense that allows you to test your queries out against your assemblies.

image

Take a look at this screenshot. You can see the intellisense at the bottom right hand of the screen. At the top left is the CQL Query Results. The top right is all of the types in the assemblies, but the highlighted ones in blue are those that were returned by the query. This all happened as I typed the query in. Actually, I got red when I typed it in the first time, because my query had some mistakes in it, but NDepend was very helpful in showing me how to correct my query.

The query editor also has different types of intellisense depending on the value.

image

I'll admit that it might seem weird to have a slider when you're just typing a number in, but the cool part is when you change the value, the query results automatically change to reflect the new value. In this case, you can watch the results of the query to get a feel for which types have the most methods.

From an agile coding perspective, NDepend ties in well with Continuous Integration. It ships with both a NANT and an MSBuild task to run the NDepend console against an NDepend project file (which is just XML). The report that it provides is insanely detailed. I'd say this where the value of application-specific CQL queries would come in handy, because you can come up with some detailed queries that are run on every CI build to ensure that the code still matches whatever design criteria was decided upon when the queries were written.

 image

For future versions of the tool, I'd think it would be neat to have a lightweight version of the CQL tool that you could ad hoc queries against assemblies, like as a Reflector addin or something. That'd be cool. Or maybe a Powershell cmdlet/PSDrive provider so that you could do something like this:

Get-ChildItem -Include *.dll -Recurse | Select-Cql -Top 10 -Methods -Where MethodCa -ge 5

Or maybe:

Get-ChildItem -Include *.dll -Recurse | Select-Cql -Top 10 -Methods | Where { $_.MethodCa -ge 5 }

I'm not sure exactly how the syntax might look, but it would be really cool :-)

Hopefully, I've given you a good picture of the some of the features of NDepend. If your interest is at all piqued, there is a "Trial / Open Source / Academic Edition" that you can download for free. Its feature set isn't quite as broad as the Professional edition, but I've used it before and it still provides a lot of functionality. Check it out!

 

Full Disclosure - I used a review copy of NDepend for this post. My company is not (yet) using this tool, but I think that there is interest. I wasn't paid to do this. <kidding>If you, dear reader, would like to pay me, please contact me.</kidding>

 

[1] I don't believe that all of the SKUs of Visual Studio have the Code Analysis feature.

Technorati Tags: ,
posted on Wednesday, March 26, 2008 6:58:49 AM (Central Standard Time, UTC-06:00)  #    Comments [1]
 Thursday, March 20, 2008

image

Anyone else find this funny? I know I do! I told you I was a beta junkie.

Technorati Tags:
posted on Thursday, March 20, 2008 7:50:31 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Wednesday, March 19, 2008

If you haven't already read Joel's commentary on the current situation with browsers, specifically the Internet Explorer 8 beta, you should check it out1. As always, read the opposing viewpoint as well. I would say that some of the comments to that post might provide more value than the sarcasm in the post, specifically this comment from Mark himself.

But you know, I'm not really posting to talk about the problems with browser compliance, web standards, or anything like that. I'm talking more about how commenters really have no clue what they're talking about. From Joel's post, "99% of the participants in the flame wars are not going to understand what they’re talking about."

The most recent post on the IEBlog revolved around how the WebBrowser control will render sites. One of the first comments is a complaint about naming regarding the WebBrowser control. The thing is, that is what it is named! Just try a Google search on the topic!

I guess this is exactly what Joel was talking about when he questioned the value of comments on sites that have enough traffic. Good thing my site doesn't get that much traffic :-) Comments to my posts (when they come) are still quite welcome!

1 While you're there, read the rest of his posts. And subscribe to his blog. Why aren't you already?

posted on Wednesday, March 19, 2008 7:15:33 AM (Central Standard Time, UTC-06:00)  #    Comments [1]
 Tuesday, March 18, 2008

I am a huge fan of the immediate window in Visual Studio. I say forget the watch window - I'd rather use code to check values. In case you didn't know, you can get values in the Immediate window by typing "?" and the variable name. Like so:

? myCoolVar

You can also execute commands at the immediate window by just typing them. It is a nice way to change values at debug-time.

myCoolVar = "some other blah"

What I didn't realize until today is that you can create completely new variables at the Immediate window as well! Just type in the variable declaration as you normally would in code. (note that you need the semi-colon in this case)

string myNewCoolVar = "I'm a brand new variable!";

Here's a screenshot of this behavior in action:

image

Right now, I'm using this behavior while working with a new WPF application. I've got an IMultiValueConverter and it is a hassle casting my generic array of objects into types, especially when I'm still deciding on the various bindings I'd like to pass in. With this, I can just set a breakpoint and use the Immediate window to play with the code.

This gets me a lot closer to an interactive console (like IRB) with .NET. Though I can do all of this with IronPython, F#, or IronRuby, it is nice to be able to do this at debug time from Visual Studio.

posted on Tuesday, March 18, 2008 10:53:44 AM (Central Standard Time, UTC-06:00)  #    Comments [2]
 Tuesday, March 04, 2008

Last night kicked out the Fort Smith .NET User Group's first meeting. It went great! I would guess that we had at least 20 or 30 people show up.

Raymond Lewallen spoke to us about Behavior Driven Design (BDD). I thought I'd share links to a few of the resources that he brought up last night.

All in all, a great presentation. Considering the breadth of information that BDD covers, I think Raymond did a great job. I hope that FSDNUG can continue to bring topics like this to the area.

posted on Tuesday, March 04, 2008 7:31:09 AM (Central Standard Time, UTC-06:00)  #    Comments [2]
 Tuesday, February 19, 2008

I was just setting at a command prompt in Vista on my laptop and I typed 'cd /' out of habit and, to my surprise, it worked! Not only that, but tab completion still behaved as expected!

I actually have been using the '/' character in PowerShell because it is easier to type than '\' (not as far to reach) and it is the default in *NIX systems as well (i.e. my Ubuntu installation).

Now granted, I probably shouldn't get used to this in the event that I inadvertently code a '/' character in one of my programs, but then again, I should technically be using the System.IO.Path.PathSeparator anyway.

I get excited about the little things.

NOTE - this might be the result of Service Pack 1 on Vista also...

UPDATE - I lied. You can type 'cd /' and get to the root, but tab completion still completes only for the current directory. In other words, if you're current directory is c:\windows\ and you type 'cd /[tab]', you'll get directories that are in c:\windows. Sorry. My excitement just dropped a little.

posted on Tuesday, February 19, 2008 5:30:08 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Monday, February 11, 2008

Last week, a small group of us traveled up to hear Jean-Paul Boodhoo present to the Northwest Arkansas .NET User Group. JP presented on advanced uses of generics in .NET (i.e. more than just strongly typed collections) though we also had a great look at Test Driven Development as well as some of the new features in C# 3.0.

The presentation was great and it got me really excited about user groups in general, which is why I'm also excited to announce that Fort Smith will be getting its own user group! Many thanks to Michael Paladino for doing a lot of the work in getting this started. FSDNUG went live last week. I'm hoping to add a feed to the site at some point so that news can easily be pushed out without continually checking the site, but for now, it is just static HTML.

Raymond Lewallen will be kicking off the group with a presentation on Behavior Driven Development. I've read about BDD and am attempting to practice TDD, so I'm excited to hear Raymond's talk. If you live in the area, be sure to come out for the meeting!

posted on Monday, February 11, 2008 12:43:38 PM (Central Standard Time, UTC-06:00)  #    Comments [4]
 Tuesday, February 05, 2008

I've found myself wishing that I could pass in more than two arguments to Path.Combine. That is, something like this:

Path.Combine(rootPath, someCalculatedPath, someKnownFileName);

As it is, Path.Combine only accepts two arguments, so I end up with calls that look like this:

Path.Combine(Path.Combine(rootPath, comeCalculatedPath), someKnownFileName);

It seems like a hassle to me. Here is a simple wrapper function (with accompanying test) that will accomplish this:

public static class FileUtils
{
    public static string CombinePaths(params string[] paths)
    {
        if (paths.Length == 0) return string.Empty; 

        return Path.Combine(paths.First(), CombinePaths(paths.Skip(1).ToArray()));
    }
} 

[TestFixture]
public class FileUtilsTests
{
    [Test]
    public void Should_combine_paths_correctly()
    {
        string expected = @"c:\some\path\to\file.txt"; 

        Assert.AreEqual(expected, FileUtils.CombinePaths("c:\\some", "path\\to", "file.txt"));
    }
}
posted on Tuesday, February 05, 2008 7:29:02 AM (Central Standard Time, UTC-06:00)  #    Comments [2]