Managing Change with .NET Assembly Diff Tools
Sometimes you find yourself wanting to compare two versions of a .NET assembly as a way getting your head around all the changes that might be happening a your project. Perhaps you're writing a Framework for consumption by other developers.
There's a few different kinds of change you want to concern yourself with.
First is the "public face" of your assembly - the interface or 'linking' contract it makes with other assemblies that might choose to reference it.
Second is the semantic contract that is made. Most folks expect certain things of your assembly. They give you two "1's" and they expect a "2" in return. Sometimes people start to rely on bugs and you have to make breaking changes.
Breaking changes like deletion or modification of existing assemblies can, of course, wreak havoc.
One word to describe the changes that happen between versions - and many versions over time - is "churn." What percentage of the "surface area" of your assembly has changed? If a large number of things change it implies that the assembly is still being actively designed, or that the problem area isn't well understood. If very few things change and/or what does change is only additive, it implies that the assembly is fairly stable and can be counted on.
Here's some tools I use to get an understanding of what's changed between binary versions of an assembly, without resorting to source-level diffs.
- LibCheck - The Standard. And oldie and a goodie. We use this tool to create reports that can be generated as part of your Continuous Integration build. The reports can be given to Project Owners (non-developers) and downstream consuming developers and gives them a very clear picture of what's changed; what should we worried about, test harder, and what should we worry less about. It also helps catch inadvertent breaking changes.
- "This tool allows you to compare two versions of an assembly, and determine the differences. The tool reports the differences as a combination of 'removed' and 'added' APIs. The tool is limited to looking only at APIs (i.e., it can't check for behavioral changes), and only compares public differences, or changes which are deemed to be 'breaking.' The tool can be used to quickly determine what has changed between one version of your assembly and another, and can help ensure that you won't introduce any breaking changes to clients of your assembly. Instructions and intended use of the tool are described in the 'libcheck tool specification' document with the zip file"
- Reflector Diff Add-In (a member of the Reflector Add-Ins Family with source available) - This tool by Sean Hederman plugs into Reflector and shows you the differences between two binary assemblies. More low-level than LIbCheck, but again, useful when you don't have source lying around.
- NDepend - A must-have tool for Lead Developers and those who have to manage large numbers of projects and seek to understand the big picture. Version 2.1 added a Build Comparison feature and extended the already powerful CQL (Code Query Language) to support queries across features. You can see what code metrics have changed between two versions, and answer questions like "did this project get more complicated in this version, or did our recent refactoring actually reduce complexity. Check out the screencast here and download here. It also integrates nicely with source level diffs, so you can jump from the macro-view to a micro-view and back.
Being acutely aware of what's changed and avoiding the surprise of a breaking change can greatly reduce the stress level of your whole team as you deliver. I use all three of these tools and I encourage you to check them out.