EntLib 3.0: Strong Naming Guidance Package
I hope you all had a great Christmas, or whatever else you may or may not choose to celebrate at this time of year. (I've probably been in the USA too long, with this amount of political correctness showing through ;-). This was my first Christmas in the northern hemisphere - we went skiing in Whistler so we had the full-on "white Christmas" experience. It was great fun, but very different to what I'm used to. But I'm back in Seattle now, still taking a few more days off work but you should start to see more of me on the blogs and on the new EntLib CodePlex site [shameless plug].
One new Enterprise Library 3.0 topic I was planning on blogging about was the new Visual Studio-integrated configuration tool, and the other few bags and whistles we've added to the tool. However David Hayden has already done a better job than I was planning on doing, so you may as well just read his summary and tutorial!
So over to plan B, which is to tell you more about the Strong Naming Guidance Package. First, a bit of history about why we built this:
Long, long ago in the dreamtime, Enterprise Library's unit tests were contained in the same assemblies as the blocks themselves (although they were in #if blocks so you could compile them out). Because the tests were in the same assemblies as the code, it was possible to test internal classes and members as well as public ones. However, because of feedback from people who didn't want the tests to "pollute" the production code, as well as the fact that the new VSTS unit testing capabilities didn't support mixing production and test code in the same assembly, we moved the tests into separate assemblies for our .NET 2.0 release. This kept everything nice and clean, but it did prevent us from testing internal methods - until we discovered the awesome power of [InternalsVisibleTo]. This attribute can be applied to assemblies to designate which other assemblies are its "friends" and hence can access internal classes and members. So we applied this attribute on the core block assemblies to tell it that the unit test assemblies were its "friends".
So far, so good - until you try to strong-name the EntLib source code. While it is possible to combine strong-naming and [InternalsVisibleTo], it is necessary to do everything in precisely the right order (including the all-important goat sacrifice at step 22) in order to make everything work. Actually the [InternalsVisibleTo] attribute needs to be updated to include the full public key (not the 16 character token, but all 320 characters of the public key) before anything will compile - and until you get something to compile, it's pretty hard to figure out what the key is.
In our defense, we did realize that it was pretty bloody hard to strong-name Enterprise Library, and we provided a pretty detailed topic in the documentation explaining how to do this (look for "strong naming" in the index). But still, it's a lot of manual work, and since we recommend that most people strong-name Enterprise Library, we (quite rightly) have received a lot of negative feedback about this being too difficult.
Luckily v3 is giving us a chance at some redemption. A few months ago, I spent a bit of time creating a Visual Studio macro that automated the strong-naming process, although it was quite unpolished and there isn't a nice way of packaging and distributing VS macros, so it was never released. But when EntLib v3 kicked off, I converted it into a GAX guidance package, and Fernando cleaned it up to something worthy of public consumption - and the result has made it into the December CTP. Here's how it works:
- Ensure you have GAX and the Strong Naming Guidance Package (in the EntLib 3.0 December 2006 CTP) installed
- Open up the EntrpriseLibrary.VSTS or EnterpriseLibrary.NUnit solutions in Visual Studio
- In Visual Studio, choose Tools > Guidance Package Manager
- Click "Enable / Disable Guidance Packages"
- Select the "Strong Naming Guidance Package", and close all of the dialogs
- If you don't already have a .snk file you want to use, right-click on a project or solution folder and choose "Create a new strong-name key pair file". This will trigger a simple recipe that does exactly what its name suggests. If you already have a .snk file you want to use, you can skip this step
- To strong-name the projects, right-click on the solution root, or a solution folder (if you don't want to strong-name everything), and choose "Strong-name all projects in this solution or solution folder".
- This will launch a wizard that prompts for the key file to use. You can use the key file you created in step 6 or any other one. Also select the "Update InternalsVisibleTo" checkbox to tell the recipe to search for this attribute and add the public key
- Click OK, and watch the magic of guidance automation!
While we built this guidance package primarily for Enterprise Library, there isn't anything that will stop you using it on any other similar complex solutions. Also while it's included in v3, it should*** work fine on v2 as well, so this may save you a few hours of your life if you need to strong-name Enterprise Library for any current projects.
One final note - in the EntLib 3.0 December 2006 CTP, we are shipping pre-compiled, strongly-named assemblies for the first time - and we plan to do this for the final release as well. I'll discuss the reasons and implications of this more in a future post, but for now I'll simply say that even though we're shipping these binaries, you'll still probably want to use the source code and strong-name it yourself to provide the most flexibility in how you use and evolve Enterprise Library.
If you have any questions, suggestions or issues with this guidance package, please let us know. And a Happy New Year to everyone!