Thursday, April 22, 2010

Clean Paths and Names in VSTF

Something I've always noticed is a struggle when on a team is creating folder structures for solutions and projects in VSTF that don't end up being redundant and hitting character limits. When you're supposed to name your assemblies with an Organization.Group.Team.Project.Assembly convention, folder path lengths can reach into the stratosphere unless you know how to appropriately massage Visual Studio into giving you the folders you want.

My recommendations for clean, short paths are as follows:
  • Pick a folder that's going to contain your solution folder, like "Source." After following this step, you will end up with a folder in Source called Org.Grp.Team.Project: Get the full path to Source, do a File > New > Project, and create an empty solution (under Other Project Types > Visual Studio Solutions) in Source. Check both the Create Directory For Solution and Add to Source Control boxes and click OK. This will open the solution in Solution Explorer.
  • To add a project to the solution and to source control, right click on the solution and do an Add > New Project. Here's where some knowledge about how Visual Studio behaves is helpful: the value you enter for Name will be the name of the folder that's created. We don't want to name it Org.Grp.Team.Project.Assembly, because that introduces a lot of redundancy and makes our paths too long. The name you want here is just the "Assembly" part. Click OK and you'll get the new project in the solution. The name next to the project entry in the Solution Explorer tree only represents the name of the project file, not the name of the assembly. To properly name your assembly, go to the project properties and change the value for Assembly Name (I also recommend changing Default Namespace) to Org.Grp.Team.Project.Assembly or whatever you like.
Now you'll have nice short folder paths and short, easy to read project names in Solution Explorer, but your assemblies will come out with the names you want.

If you need to change a folder name later, you don't need to worry about the project file in that folder, but you will need to fix project references that point to that project, as well as solution files for solutions that contain that project.

My last tip is that it's sometimes a good idea to copy the directory mapped to the project root to a temporary backup, wipe out the original, and do a full force get from TFS. This will eliminate any garbge folders and files that have accumulated on your machine when doing things like renames or removing projects or files you decided you didn't want from a solution - the backup is just in case some of those folders or files aren't garbage, like important stuff that didn't get checked in for some reason.

Wednesday, April 21, 2010

The IDisposable Pattern

I've been working on a little project involving creating a class that implements IDisposable, and I was curious about the pattern I had frequently seen by Reflectoring BCL classes and looking at other peoples' code that involved a Dispose(bool dispoing) method, calls to GC.SuppressFinalize(this) and a few other things. I started digging and hit upon a huge amount of detail regarding the optimal IDisposable pattern that the framework designers intended, destructors/finalizers, how the memory of managed resources is recycled vs. how unmanaged resources are handled, where Dispose(bool disposing) enters the picture, and a lot of other fascinating stuff.

I gathered up a bunch of links with a lot of technical detail and I was gearing up to write a big post about implementing the pattern properly, but then I found Shawn Farkas' excellent MSDN Magazine article "CLR Inside Out: Digging into IDisposable" and realized that the work had already been done. In just a couple of pages, this article explains in extremely lucid detail how the pattern works and why it should be implemented just so.

If you're looking for an extreme amount of detail, Joe Duffy posted an update to the "Dispose, Finalization, and Resource Management" chapter of the Framework Design Guideline on his blog in 2005.

Here were my key takeaways after researching all of this:
• C# doesn't really have "destructors." It only has "destructor syntax," which is the required shortcut for implementing Finalize() on a class (the compiler will warn you if you implement a method called Finalize()). It basically ensures that Finalize() does all the things it really should do in every single case: marking it as protected, carrying out all actions inside a try block, and calling base.Finalize() inside a finally block.
• If your class is sealed and you only use managed resources (i.e. stuff that needs Dispose called on it), just implement Dispose(). For each resource, check for != null and then call Dispose() on it. That's it.
• If your class isn't sealed, implement the full pattern (including GC.SuppressFinalize(this)), but leave out the finalizer unless you are using unmanaged resources. Adding a finalizer incurs a cost, even if you Dispose of the object and call GC.SuppressFinalize(this) in Dispose(). By calling GC.SuppressFinalize(this), even if you don't have a finalizer, you ensure that you suppress finalization for any subclass that has a finalizer.
• Any class with a finalizer should implement IDisposable. By the same token, if you inherit from an IDisposable that has a finalizer on it, do not define your own finalizer - the ancestor's finalizer will call your Dispose(bool disposing) method, where the cleanup is done.
• It often makes sense to contain some kind of state in your object so it can tell if it has been Disposed of. You can have instance methods check this state and throw ObjectDisposedExceptions as appropriate.
• A subclass of an IDisposable that properly follows the pattern only needs to override Dispose(bool disposing). Its implementation of it should dispose of resources using the same basic pattern and then call base.Dispose(disposing).
• Dispose() and Dispose(bool disposing) should never fail, but you shouldn't suppress exceptions that may be thrown from them. Often what makes sense is a try/finally where the resource cleanup is done inside the try block and a call to base.Dispose(disposing) is done inside the finally block.
• Finally, after all this talk about finalizers: you should basically almost never be implementing one. I don't know a whole lot about unmanaged resources but what I've read is that after .NET 2.0, pretty much all unmanaged resources can be controlled through SafeHandles, which take care of finalization for you in a robust way.

A few other good resources:

• Bryan Grunkemeyer's post on the BCL Team Blog about Disposing, Finalization and Resurrection.
• A good StackOverflow conversation about implementing the pattern.
• The MSDN documentation about implementing a dispose method.
• A little bit of info about the "freachable" queue and what happens when you put a finalizer on a class.
• A bit of clarification on "destructor" vs. "finalizer" as pertaining to C#: here and here.

Tuesday, April 20, 2010

Disabling Moles Pre-Compilation

One thing about Moles that I've found a bit annoying is that the Mole types always get compiled into an assembly. This is fine when you mole something like mscorlib because it's not going to be changing, but when you mole your own code, the result is that you have a dependency on a binary file that keeps changing over and over. If you check your code into source control, this is a nuisance.

It turns out that if you open a .moles file and add <Compilation Disable="true"/>, Moles won't generate an assembly and will instead put the source directly into your test project. In my opinion, this is much cleaner. Now you don't have binary files to keep track of and fewer assembly references in your test project.

Saturday, April 17, 2010

Browsing the GAC

I learned a long time ago that there was a way to disable the Windows shell extension that puts a pretty but often annoying face over C:\windows\assembly\. It's nice to be able to drag assemblies to it or do a right-click/delete, but it's irritating not to be able to treat it like a regular folder when you want to.

The standard way to disable the facade is to flip a bit in the registry: in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion, set "DisableCacheViewer" to dword:00000010. You can flip it back to all zeroes if you want to turn it back on.

I happened to be doing a bit of digging to find this information again for the 20th time and found the first comment on this blog post here, which says that if you type C:\windows\assembly\gac into the Run box, it will disable the shell extension for that Explorer window and let you move around the GAC folders. Very nice. It works with other sub-folders of assembly as well, so you can browse straight to gac_msil if you like. It also works from the Win7 start menu smart-search text box, but it won't work if you type it into an Explorer path bar.

The standard warning applies: don't move stuff around in the GAC or add or delete things manually. The standard explorer view is best for being able to quickly copy assemblies out.

How I Came Back to OneNote

Around the time I was in high school I started paying more attention to the ways I try to organize information and "present" it to myself. Since then, I've been constantly experimenting and revising the way I take notes and keep myself organized. I just went through a flurry of activity in the last few months and wanted to share about it.

I have found my way to OneNote a few times since its release, and I have always ended up letting it go. I spend a month or two sorting my thoughts into neat hierarchies of notebooks, tabs and pages, diligently typing in meeting notes and other thoughts, and at first the organization seems to make so much sense. Unlike some people, though, my problem isn't that my will to organize everything falls apart. My problem has always been that my notebooks become big black holes of information: I put lots of great things there and then never look at them again. I would always play along with the multiple levels of nesting and hierarchically organize everything, and the information gets buried and a lot of links between important clusters of notes would get lost. I'm not talking about hyperlinks, I'm talking about the importance of mentally associating multiple items with each other.

When my brain finally turned out the preceding sentence a month or two ago while I was trying to figure out how to organize myself, I thought, "clearly I learn and store information visually/spatially, so why aren't I taking notes that way?" I started using Post-Its, but quickly came to hate their size and unneeded stickiness. That weekend, while I was at the store, I picked up some colored notecards and erasers and put together a Hipster PDA. I loved it and my new ability to spread out and rearrange notecards, for about a month: My handwriting is decent, but the keyboard is a more elegant weapon for a more civilized age. I've gotten so used to almost being able keep up with my brain dumps by typing that handwriting feels glacial by comparison. Plus, by moving back to pencil and paper, I was losing out on so many useful tools that are so obvious on a computer.

My next stop was Win7's sticky notes. They're simple but they're not reliable, they're limited to your desktop and they offer very little useful functionality. This lasted about three days, but it got me wondering what kind of spatial organization tools were available in OneNote. I did a little searching and bumped into OneNote Canvas, which immediately looked familiar because I've seen demonstrations done with pptPlex before. I got as far as installing it and getting to the screen where it recommended not using it if you share your notebooks via fileshares (sorry Canvas, but you lost me there). Going back to look at the features, I realized it probably wasn't that great of a fit anyways - the focus was still on pages, as if one was writing in a Word doc and just wanted to clump some pages together. I wanted to get away from that - I wanted to clump ideas together and make things easy to see. I looked at the remainder of the digital sticky notes on my desktop and thought, "why can't I just use OneNote this way? What if I just shut off the obsessive-compulsive instinct to separate everything into notebooks, tabs, pages, paragraphs and bullet lists and just started with a single blank page?"

I fired up OneNote, and I don't think I've closed it since. I think my "note cloud" (this blog post serves as dated proof of prior art of that term and concept if I ever get to patent it!) is here to stay.

The main attraction is my note cloud, a single page that has note containers and a few other types of information scattered all over it. All notes "start" here - if I go to a meeting, have an idea, or someone comes in my office and I need to write something down, it goes in the note cloud. Over time, if I end up having a few scattered blocks that are related, I can just drag them together to associate them. If a block starts to take on content and structure, I'll move it to a new page and replace it in the note cloud with a hyperlink to that page (in OneNote, you can right-click any notebook, tab, page or even individual paragraph and generate a link to it that gets sent to the clipboard). I frequently zoom with Ctrl+MouseWheel to get a better view, so I'll change the font size, weight, highlight color or text color of important things or tag them with a start or something else appropriate. This is actually where I thought of the "note cloud" name - the different font sizes and weights interspersed look a lot like a tag cloud. I don't have a tablet PC, but I can use the drawing tools with the mouse to scribble a broad highlight or circle a few things. The familiar Ctrl-F is "find on this page" in OneNote and I make use of it frequently.

I look at my note cloud constantly and I'm always writing stuff there - it's almost like a desk blotter that I can scribble notes on. I don't have to worry about losing or forgetting about important notes because I'm looking at them all the time, and in the case of a big cluster of notes that I don't need all upfront, I instead have a single link to another page that will take me straight to the content. I've also got another page right next to the cloud, "note cloud trash", where I'll paste old notes cut from the cloud that I might want to have around for a bit to remind me if I did or didn't do something. As this page grows, I'll probably burn the old brush out every once in a while.

So far, I've only mentioned the most basic features in OneNote. I doubt there's anyone that uses them all of OneNote's features (there are zillions of really important features that aren't ribbon buttons or context menu items, but things that "just work," a lot of them having to do with Office suite integration and drag/paste support), but there are a few I've come to really love that have basically turned OneNote into a "smart desktop" for me.

The first is that OneNote is starting to replace my web favorites/bookmarks for research-related tasks. Bookmark titles and folder organization just don't cut it for me for anything except general favorites. With OneNote, I can paste in URLs or drag favicons in from the browser and clump a bunch of links together with other text to associate all of them. Never again will I put a web bookmark on my desktop, lose a bookmark for a specific topic, or wonder if I bookmarked something or not - I have developed a new reflex that automatically pastes URLs of interesting pages into OneNote. This is the new school of research and gathering sources: I remember thinking that gathering and citing sources was such a chore in school, but with OneNote I've got a list of seven or eight interesting links just for this blog post (and let's be honest, this post isn't even that interesting). Amassing links for later perusal and comprehension (or printing for take-home reading, which I've become a big fan of) is incredibly easy.

Another organizational trouble spot I've had since I embarked on my career and was responsible for "action items" is how to keep track of requests sent to me via email, and how to remember to stay on top of people that haven't yet completed requests I have made of them. For the latter, I used to have a set of "waiting on" pages in OneNote, but like everything else they got subdivided into oblivion and buried. I learned firsthand that mail folders are meant for archive organization when I tried to work with a "Later" folder for stuff I didn't want in my Inbox. I summarily renamed that folder "Never" right before trashing it. I never used it because I knew I'd never look in it. Why did I have so many places (mail folders, notes pages, bookmark lists) to look for stuff I wanted right in front of me all the time?

My favorite new trick is to drag emails from Outlook into OneNote and select "insert a copy of the file onto the page". This gives you a bite-sized email icon with the subject line right on the page, and you can double-click it to open it. This has allowed me to do something I have wanted to do for ages, which is to stop using my Outlook folders, including my (now empty!) inbox, for information that I want to have in front of me. I can drag multiple emails into a little group with some text notes to associate them all. If I have an email associated with a task and I complete that task, I can just double-click the email and Reply to it. If I am waiting on someone else to complete something, I can put my request email next to the note and double click it if I want to send a reminder. If a lot of emails come through for a given task I'll replace the one in my OneNote with the newest, so I can see the full thread. The object in OneNote is a copy of the email, so I can sort the original however I like, and if I really need to find it in my mail folder I can use information from the copy to search for it. I've also started using this feature to keep a little collection of emails that might benefit me during the next performance review - I hate keeping copies of emails in my mail folders but I want to sort emails appropriately based on project or task, so I keep the copies in OneNote, along with any other notes or information I can use at review time.

If I ever get around to figuring out how to file feature requests for Office products, I'd love to see first-class support for spatial note taking like this. Even if that doesn't happen, though, I have a few ideas that would help out my workflow and make it even more effective:
• Make zooming and panning a little easier. Zooming is really flaky around the edges of a page and doesn't like to stay centered on the cursor, and zoom settings are used application-wide, not per page. Panning by holding middle-click seems to amplify the mouse sensitivity. Mine is already very high and when I try to pan this way the viewport jumps all over.
• Provide a per-note-container option to make an outline around the note cluster. This would help to automatically visually separate notes that are close together but aren't really associated.
• Some way to link to (as opposed to copy) a whole conversation-threaded Outlook 2010 email thread
• OneNote has a bug where if you drag a favicon from a page with a long URL into it, the text of the entire URL will get pasted, but only about 100 characters of it will become an active link, and the link target will only include those characters (i.e. you have a broken link and you need to recopy the URL to fix it). The workaround is to copy the URL from the address bar and paste it instead of dragging the favicon. Edit: This is incorrect; copying and pasting the URL runs into the same problem, and it's very annoying. I'm using OneNote 2010 Beta but I'll have to see if it's fix in RTM.

We'll see how long this strategy lives for, but I think it's going to stick around for quite a while. The nice thing about it is that you can scale it: if you have tons of discrete things to keep track of, you can still make pages or sections or whole notebooks for them and use your cloud as an index/table of contents with links to stuff so it's still visually in front of you at all times.

My favorite part out of all of this is that I've used the verb "associate" a couple times in this post, but I'm not referring to a feature of OneNote or another piece of software - I'm referring to a feature of the human brain. With my note cloud, everything is right in front of me. By using the simple features of the tool to organize information spatially, I can rely on my brain's cognitive map to make connections and remember things. I finally feel comfortable doing a bunch of work and then dropping it for a while because I know I'm going to be able to pick it up again later. I think this is about as close to a mind/machine merge as I'm going to get until someone releases some new hardware.

Wednesday, April 14, 2010

Motivation

I'm not going to add a big preface to this video, except to say that it's one of my favorite TED talks (if you aren't familiar with TED, go get a week's worth of food and water and click that link, and don't forget to remind your loved ones you're still alive). This is the author Dan Pink talking about what motivates people, particularly in the workplace.



I haven't read Mr. Pink's book related to this video, Drive, but as someone who is pretty dialed into his career and loves learning, I really identify with the message he delivers in this talk. One of my uber-managers, about four levels above me, gives a talk occasionally about performance. He puts a big emphasis on thinking about and understanding what you really want out of your career, whether it's money, respect, recognition, whatever. Especially for someone like me, "autonomy, mastery and purpose" is a tough list to beat. "The freedom to become better at doing things that make a difference."

I really like finding the right words to convey an idea, and those three in particular really shine on their own. What's interesting to me is that they work so well together, but the way one achieves each of those items in the workplace is different. With some exceptions, autonomy is something granted to you based on where you work and who you work for (not to say you don't have any control over that). Mastery is something you have to earn through study, practice and introspection. Purpose is something you have to find - you can't ever really have purpose given to you, only suggested. It doesn't become your purpose until you internalize and embrace it.

If I was in charge of a large corporation, I would not only be interested in granting my employees these three things, but I would be looking to hire people that truly desired them. Mr. Pink says that most everybody wants these things, but I have a feeling that the people who want them the most are the ones you want working for you.

Thanks to Lessons of Failure for reminding me about this video. Great post too!

TFS Labels

I've been spending some time reading up on TFS and how branching, labeling and some of the other more advanced features work in an effort to concoct a new code management process for my team. Our current process is nice and simple, but it's a little bit too simple when we're trying to maintain a clean build for test, introduce fixes that require multiple developers or breaking changes, and think about/work on the next version all at the same time.

In a few future posts I'll talk about some of my findings regarding branching (virtually all of them come from the TFS Branching Guidance, which I cannot recommend enough), but I wanted to devote a couple paragraphs to what I have learned about labels in TFS.

Prior to today, whenever I heard "source control label", I thought of it in the most simplistic sense, i.e. the way it was implemented in Visual SourceSafe. Point at a folder, create a label name, and poof - you have a snapshot-in-time of the codebase. If you load up the history for a file, you can clearly see which revisions were labeled and what the label name was.

Labels in TFS do not work this way. The biggest tip-off to this I had was this blog post, but there's no analogy or walkthrough/instruction in there that shows you what he means. I want to provide both of those things here.

The analogy: Applying tags to photos or music. Most modern personal media-organization applications have functionality that lets you "tag" individual items and then view a list of all items that have a specific tag. Windows Live Photo Gallery is a good example:



You can create a new tag at any time and apply it to as many images as you want. You are always free to remove the tag later, individual images can have multiple tags on them, and deleting a tag doesn't delete the tagged images, it just removes that tag from all images that have it. On the main WLPG screen, you can click a tag name in the list of tag names and it will show you only images with that tag applied.

TFS labels use the exact same concept, but with a twist that makes them way more powerful than the tags on your photo album. When you apply a label, you aren't applying it to a file, you are applying it to a version of a file.

Is this a big deal? It depends on whether or not you make use of it. You can definitely continue to use labels in much the same way as you can in VSS, simply tagging a whole tree with a label at a given point in time. You can also get more fancy with them, using them to form collection of specific revisions of files.

Labels come with a big warning though - labels themselves are not version controlled, meaning that there is no way to track or audit the history of activity on a label. Plus, labels don't keep copies of versions in case of a file deletion, so if a file gets deleted, any label that relies on a version of that file is essentially hosed. These reasons are why it makes more sense to branch for major releases instead of labeling them.

Here are a couple good resources on TFS labels: