I like to abstract diagnostics (logging and performance counters) into a separate interface or abstract class. But it becomes tedious to manually keep the fake diagnostics (used to test that that proper diagnostics calls are made), dummy diagnostics (when I just need something to pass around), console loggers (used for command line applications) and production logging in sync with the interface. And it is boring to do manually since the first three essentially have the same implementation for all methods.

So what I've started to do is to use T4 to generate those three files but also the interface. Production logging is still updated manually but I think it is important to consider exactly what events and performance counters should be triggered by each event. And I want to keep my diagnostics definition simple. So this is what I do:

  • I created a include file in a common place (solution item) that defines some common classes to generate method declarations and method calls.
  • I created a include file in a common place (solution item) that defines my interface.
  • I created one template (where needed, typically in different projects) to generate the interface, fake, dummy and console logger.

I find it easy to work with the T4 template files (even though it feels a little like you're back to classical PHP/ASP style programing, but it does remove some boring tasks. And the error messages you get when you have errors in your template have been pretty good for me so it has been easy to correct the problems.

The only downside with this is that when you change the include file you need to transform the templates manually in visual studio. Unless you install an SDK that defines a build target you can use. This Is because the T4 transformation happens when the template file is saved, not when one of its dependencies change. I did however find this clever way of getting around it which is essentially running the tool manually as a build step. I prefer that over forcing additional SDKs to be installed by everyone including the build servers. I only hope this will be just working in a future version if VS.