net, autofac comments edit

For those of you who use Autofac, I thought I’d provide a bit of a project update to let you know what’s going on.

First, there’s been a little shake-up in the project ownership role. Nick Blumhardt, original creator, will still be working on the project as a committer but has stepped down as an owner. Alex Meyer-Gleaves will remain an owner, and I’ve now been made a co-owner with him. Nick has posted a formal announcement in the Autofac newsgroup. Huge props to Nick for making such an awesome product; I hope I can help carry that forward with as much success.

Next, we’re working hard on the upcoming release of Autofac, which we’ll be calling 3.0. The core Autofac assembly will be a Portable Class Library so we can support WinRT, Silverlight, and full .NET. That will potentially mean a few small breaking changes, but it shouldn’t be too bad to adjust to. We’ll be adding NuGet packages for all of the contributed projects (which are now the “Autofac Extras”). Dependencies have been updated so we’ll link to more current releases. We’re running down the issues list to see if we can get as many resolved as possible before the final release. And we’ve done a ton of updating to the build and static analysis process so it’s easier to work on, easier to extend, and adds a lot more confidence to the shipping builds. I really think you’ll like it.

I anticipate that should all be showing up Real Soon Now. You can follow the progress on the Autofac newsgroup.

media comments edit

As part of my media center solution, I have a fairly rigorous media and metadata management process that goes on any time I acquire new media. I figured I might give folks a glimpse behind the curtain so you know what goes on. Broken down by media type, here’s how it goes from acquisition to “in the system.”

  • Audio (Music, Audiobooks)
    • CD
      1. Add to Music Collector.
        • Enter the CD info, generally by bar code.
        • Clean up artist or album name data if needed.
        • Synchronize collection with Music Collector Online.
      2. Add to iTunes.
        • Rip CD as Apple Lossless. Files end up on Windows Home Server for later serving via Asset UPnP.
        • Clean up metadata as needed - artist, album, cover art, etc.
      3. Synchronize iPod.
      4. File the disc.
        • Pull the disc, front cover, and back cover out of the plastic box.
        • File the disc with the front cover in a DJ box.
        • File the back cover in an expanding folder.
        • Recycle the plastic box.
    • Digital (MP3, AAC)
      1. Download from original source (usually Amazon MP3).
      2. Add to iTunes.
        • Drag into iTunes. Files end up on Windows Home Server for later serving via Asset UPnP.
        • Clean up metadata as needed - artist (last, first), album, etc.
      3. Synchronize iPod.
      4. Add to Music Collector.
        • Add the digital files to Music Collector.
        • Clean up artist or album name data if needed.
        • Link to a Music Collector album profile.
        • Synchronize collection with Music Collector Online.
  • Video (Movies, TV Shows)
    • Blu-ray
      1. Add to DVD Profiler.
        • Update the local profile database for my existing collection.
        • Enter the disc info, generally by bar code.
        • Synchronize collection with DVD Profiler Online.
        • Backup the local profile database.
      2. File the disc.
        • Pull the disc cover, discs, and inserts out of the plastic box.
        • File the disc with covers and inserts in a DiscSox storage set.
        • Recycle the plastic box.
    • DVD
      1. Add to DVD Profiler.
        • Update the local profile database for my existing collection.
        • Enter the disc info, generally by bar code.
        • Synchronize collection with DVD Profiler Online.
        • Backup the local profile database.
      2. Rip the disc and add to media center.
        • Rip the disc with DVDFab HD Decrypter.
        • Update the folder name with the disc image so XBMC can scrape data.
        • Update the DVDID XML file if needed for Windows Media Center.
        • Copy the disc image onto my NAS (Synology DS1010+) for later serving.
        • Start XBMC on my master computer (read/write access to the database) and let XBMC scraping add the new item to the database.
        • Verify/correct any XBMC metadata issues.
        • Start Windows Media Center on my master computer and wait for it to add the cached metadata XML file to the system.
        • Correct the metadata using DVD Library Manager including better cover scans.
      3. File the disc.
        • Pull the disc cover, discs, and inserts out of the plastic box.
        • File the disc in a binder.
        • File the cover in an expandable folder.
        • File the inserts in a small photo box.
        • Recycle the plastic box.
      4. Optional: Convert for Mobile Use (via Handbrake). If I do this, I put it into iTunes and then sync iPod and iPad.
    • Digital
      1. Redeem the “digital copy” code (in iTunes).
      2. Update any metadata as needed.
      3. Sync iPod and iPad.

You’ll notice that, at this time, I’m not ripping Blu-ray discs to any media server/digital format. I don’t have a ton of them and they just eat disc space, so I’m not there yet. I’ve also still not figured out a good compression format that retains the surround sound, which is why I rip full images from DVDs.

You’ll also note that I don’t really buy digital videos. The only ones I have are from those “digital copy” things you get with some disc purchases. There’s no DRM-free equivalent that they sell videos in right now, so these are “neat” but aren’t my system of record and probably won’t be if I have anything to say about it. (Which, someday, I may not

  • thanks Hollywood…) The only time I even use these is if I’ve got my iPad on a trip or something. I don’t/can’t use them through my media center.

For all the folks that think maintaining something like this is free… now you see it isn’t. Or maybe it is if you don’t care about the housekeeping part, but I can see that after you get to a sufficient size then having no organization (or not caring) may render the system unusable, which is what I’m trying to avoid.

General Ramblings comments edit

Phoenix is not quite two, but in her words, “I big.” She is starting to become very independent, or at least she tries to be.

Phoenix in her Batman
raincoat

In some cases she doesn’t even want you to read her a bedtime story. She’ll do that herself. If you try to sit next to her or point things out, she’ll take the book and move somewhere else.

She really likes music and dancing, and there are rules around that you must follow. If she’s dancing, you need to get up and dance. If you sit down, she’ll come over and grab your hand to pull you back up so you’re dancing again. (She says, “pulllllllll” as she pulls you.) If you stop dancing and just stand, you get scolded (“Daddy! Dance! Go!”). For a while dancing amounted to bouncing up and down and clapping. Now it’s more of a “march” where you take big steps and swing your arms.

Her favorite music is electronic with a heavy disco sort of beat, particularly the LMFAO album Sorry for Party Rocking. We listen to that nearly every day in the car on the way to day care. The conversation goes something like this:

Phoenix: Daddy, I want rock. [points at the radio]

Me: You want to listen to the radio?

Phoenix: OK*. I want rock.

Me: Party rock?

Phoenix: OK.

* Phoenix only really says “OK” or “no.” Sometimes you’ll get “yeah,” but generally it’s “OK” for “yes.” I think she gets this from Jenn, who basically has “maybe” and “no.”

I scroll to find the album and start playing it, at which point any bad morning changes to smiles and clapping and giggling. She really loves her party rock. She can’t even wait between songs - that three second pause? - before you hear, “I want rock!” Don’t try to put something else on, she’ll tell you no. In some cases if she doesn’t recognize the first few notes, even if it’s just another LMFAO song she doesn’t hear often, she’ll say no. She wants that specific album.

We had that conversation this morning, but when we finally got to day care she saw we were there and started crying. “No, Daddy! I want rock!” Don’t turn that party rock off, there’s gonna be a problem. She knows what she wants.

This morning she knew she didn’t want socks. Some days she does, some days not. When she doesn’t, she’ll try to put the socks back in the drawer after you get them out. We took the socks downstairs to put them on her. The whole time, she was acting like there was something upstairs she wanted, but we were trying to get ready so kept telling her no, it’s time to get ready to go.

Eventually it came time to put the socks on and she had a total meltdown like we packed the socks with acid before putting them on her. Fine, no socks. We pulled the socks off and she grabbed them both and pointed upstairs. “Back.” She wanted to put them back. She walked Jenn up the stairs, went into her room, and put the socks back in the drawer. Then she picked up a pair of socks that didn’t make it into the laundry bin and put them in the bin. Finally all was right with the world. I’m guessing that nagging thing she wanted upstairs was to put those socks in the bin…

…which meansI successfully passed along my OCD to the toddler. A place for everything and everything in its place. Jenn, you’re outnumbered!

net, ndepend comments edit

I recently updated to NDepend 4. I got an early preview of the sweetness that is CQLinq (code query using LINQ syntax) so I couldn’t wait to dive into the full deal.

For new users of NDepend, the “getting started” part of things isn’t too different from NDepend 3 - same download/unzip/run xcopy-style installer, same UI, same super-robust reporting. I wrote a good entry on getting started with NDepend 3 and most of that still applies here so I won’t rehash it.

NDepend home
screen

For existing users of NDepend, CQLinq is really the big deal in this latest release. That alone is really worth the price of admission. But there are also some other cool things in there. Let’s take a look.

First, CQLinq. If you’ve written code queries in the old SQL style of syntax, you’ll love the new LINQ style.

Let’s say you want to find all the methods that start with “To” in your project (like “ToString()” or “ToDecimal()”). The old SQL style query looks like this:

SELECT METHODS WHERE NameLike "^To.*"

The new CQLinq looks like this:

from m in Methods where m.NameLike("^To.*") select m

Or you can use the extension method style of LINQ syntax if you like that better (which I do):

Methods.Where(m => m.NameLike("^To.*"))

In this simple example it may not be too clear what the power is. But if you look at the result set, you see both your methods and methods from the framework assemblies you referenced. Let’s work in another of the features of NDepend - analyzing “JustMyCode”:

JustMyCode.Methods.Where(m => m.NameLike("^To.*"))

Now the result set is just the methods from your code. Oh, but that includes some crazy ToString methods that the compiler generated. Let’s remove those, too, and maybe even order the result set for easier reading.

JustMyCode.Methods.Where(m => m.NameLike("^To.*") && !m.IsGeneratedByCompiler).OrderBy(m => m.Name).Select(m => m)

The results of the query look like this:

Demo query results in
NDepend

Now, that’s pretty sweet.

All of the base queries have been rewritten in CQLinq so you can really see some great uses. Here’s the built-in query that checks to see if your constructor is calling any virtual methods:

warnif count > 0
from t in Application.Types where
   t.IsClass &&
  !t.IsGeneratedByCompiler &&
  !t.IsSealed

from ctor in t.Constructors
let virtualMethodsCalled = from mCalled in ctor.MethodsCalled
                           where mCalled.IsVirtual &&
                                (mCalled.ParentType == t ||
                                 t.DeriveFrom(mCalled.ParentType))
                           select mCalled
where virtualMethodsCalled.Count() > 0

select new { ctor ,
             virtualMethodsCalled,
             t.DerivedTypes }

You can really dig into your code like this. I find this way easier to use than the previous SQL-style syntax.

Now here’s the bit that sort of blows me away:

You can use this API to write your own custom analysis tools.

This is also a new thing with the 4.0 version of NDepend. NDepend comes with a bunch of sample applications that show you how to use the NDepend API. There’s also plenty of online documentation. I will warn you, this isn’t for the faint of heart. If you’ve ever written a custom FxCop rule, it looks to be roughly that level of complexity. The trouble isn’t in running the CQLinq to get your analysis results - that’s the easy part. The complexity is in getting the analysis results in the first place. You’ll most likely want to make heavy use of the sample code and “borrow” from it when making your own tools.

Once you build the sample app, you get a console app with some old-school console menus that show you different options.

NDepend Power Tools
Menu

I thought I’d try the duplicate code detector. Here’s the output running it on one of my projects (I had to blur a few things out, but you get the idea):

NDepend duplicate code
finder

Not pretty, but you can see the power there. You could do all sorts of things with that - Visual Studio add-ins, PowerShell scripts for analyzing across solutions… all sorts of ideas. (Keep in mind that with CQL and CQLinq you can basically replace FxCop rules with queries. Using the API is primarily for more in-depth analysis tools. My point in saying the relative difficulty is around the difficulty of writing for FxCop is that with FxCop there’s a lot of interesting custom stuff you have to learn to wire things up - the object hierarchy, the way you get analysis results, the way you insert yourself into the process, etc. It appears there is roughly that level of learning to be done to write a power tool using NDepend.API. That said, if you’re just interested in doing analysis and querying… you can just write CQLinq pretty easily inside NDepend and skip the API part.)

With the power of CQL and CQLinq comes a little bit of a learning curve in the form of some hard-to-diagnose gotchas when things aren’t finding what you expect. I found a couple while crafting the above example query:

  • You have to add a Select after an OrderBy or you get an error. Notice in that last example query I order the list of methods by name. In standard LINQ, you order it and you’re done. In CQLinq, you get an error telling you that you need a Select after that. So… add a Select and you get the ordered list as you expect.
  • IsGeneratedByCompiler doesn’t mean “has the CompilerGeneratedAttribute.” If your application has, say, some generated web proxy classes or some things that have the [CompilerGenerated] attribute on them, you won’t find them by using the IsGeneratedByCompiler predicate. IsGeneratedByCompiler only finds things that really were generated by the compiler
    • iterators, anonymous methods, that sort of thing.

Learning about NDepend takes effort. It’s not something you’ll just “figure out” without watching the videos or reading the docs. And there’s a lot of documentation. And a lot of videos. It’s thick, it’s technical, and it’s hard to get through. In some cases, the language/phrasing of the documentation belies that the author isn’t a native English speaker, which makes it sometimes a bit harder to parse for a native speaker like myself. Stick with it, though. It’s worth the effort, especially if you’re working on a larger enterprise project. Not only is it a great way to learn about NDepend, it also helps you learn about good code quality and metrics used to analyze code.

Speaking of doc, you can find it everywhere. Even in tooltips. Hover over a part of a CQLinq query and you get doc for that element:

NDepend support is really good. I think Patrick does it all by himself, so when you ask a question, you get an answer straight from the source. We worked through a recent weird issue and resolved it almost in real-time.

The UI continues to be a little confusing. Each version gets better, guiding you to steps like “what to do next,” and given the robustness and complexity of what NDepend is doing I don’t know how I’d do it better… but there are still little things that get me. For example, I updated the location of analysis report output and wanted to re-run the report, but couldn’t find the option to do that. It turns out the ability to re-run the analysis isn’t in the Analysis menu - it’s behind this little button in the bottom right corner of the window.

The button in the bottom right corner of the window is really
important!

IntelliSense in the query window can sometimes be frustrating. Maybe I type too fast, but I find that sometimes it autocompletes when I didn’t want it to, or the cursor “jumps around” as I backspace. This isn’t new in 4.0 and I can’t consistently reproduce it.

The mouse scroll wheel doesn’t do what you think it does. Normally in a window with a scroll bar, scrolling the mouse wheel will scroll the window up and down. Zoom is usually done by holding Ctrl and scrolling. In the Dependency Matrix view the mouse wheel zooms without holding Ctrl (even though there’s a scroll bar and I generally want to scroll more than I want to zoom in that window). In other views, the mouse wheel does nothing - even if there is both zoom and scroll available. Definitely takes some getting used to.

My NUMBER ONE problem with NDepend, though, persists to this day: You STILL can’t use environment variables in framework folder paths. For example, I may have Windows installed on my C:\ drive but moved Program Files to D:\. If I set up an NDepend project on that machine, I won’t be able to use it as part of my build because the build server doesn’t have the same setup. I’ve reported this to NDepend support, so they’re aware, but it’s still never been fixed. It’s a small thing, but in an environment where you truly need NDepend - a large, enterprise shop with build server farms and lots of developers and architects - this is a huge oversight.

Despite all that,NDepend is a totally valuable tool. If you think your code is good now, run it through NDepend and dig in. You can make your good code great.

Full disclosure: I got a free personal license from Patrick at NDepend. However, we have also purchased several licenses at work and make use of it to great benefit.

UPDATE: After the initial posting of this article, I got some answers on how to do some of the things I was stuck on, so I added that info.