Rhino Generators
Like I said, I got envious from the Eleutian guys, and I decided to try to implement a very simple task with code preprocessing. After a small false start (choose the wrong code parser), I was able to come up with a preprocessor that could take this:
[PerformanceCounterCategory("TestFoo")]
public abstract class Performance
{
[PerformanceCounter(PerformanceCounterType.NumberOfItems64)]
public abstract PerformanceCounter TotalItems { get; }
}
And transform it to something like this:
public class PerformanceDerived : Performance {
private HandleSetup _setup = new HandleSetup();
private System.Diagnostics.PerformanceCounter _TotalItems =
new System.Diagnostics.PerformanceCounter("TestFoo", "TotalItems");
public virtual HandleSetup Setup {
get {
return this._setup;
}
}
public override System.Diagnostics.PerformanceCounter TotalItems {
get {
return this._TotalItems;
}
}
public class HandleSetup {
public virtual void Run() {
if (System.Diagnostics.PerformanceCounterCategory.Exists("TestFoo")) {
System.Diagnostics.PerformanceCounterCategory.Delete("TestFoo");
}
System.Diagnostics.CounterCreationDataCollection counters =
new System.Diagnostics.CounterCreationDataCollection();
System.Diagnostics.CounterCreationData TotalItems_Counter =
new System.Diagnostics.CounterCreationData();
TotalItems_Counter.CounterName = "TotalItems";
counters.Add(TotalItems_Counter);
System.Diagnostics.PerformanceCounterCategory.Create("TestFoo", "",
System.Diagnostics.PerformanceCounterCategoryType.SingleInstance, counters);
}
}
}
Which means that I can the do this:
[PerformanceCounterCategory("TestFoo")]
public abstract class Performance
{
static PerformanceDerived instance = new PerformanceDerived();
public static PerformanceDerived Instance
{
get { return instance; }
}
[PerformanceCounter(PerformanceCounterType.NumberOfItems64)]
public abstract PerformanceCounter TotalItems { get; }
}
And now I can get:
Performance.Instance.Setup.Run();//init the counters
Performance.Instance.TotalItems.Increment();//use the counters
The main advantage here is that I can sometimes reach to a high number of counters, and it is annoying to try to manage them independently.
At the moment I am having issues trying to decide how I should expose this, though. There are two options:
- MsBuild Task - Simple & easy, won't run each time that I run the file, will run as part of the build.
- VS Custom Tool - A bit hard to developer, much harder to deploy, will not run as part of the buiild but will run whenever I change the file.
Comments
+1 msbuild task!
Comment preview