Attribute lifecycle
For some reason, I had this assumption that the lifecycle of System.Attribute instances was singleton. Javier Lozano wrote a quick test to prove me wrong after I looked at ways to inject services into attribute instances. I really should have read the CLR via C# book a little more closely, as it states (emphasis mine):
If you want to construct an attribute object, you must call either GetCustomAttributes or GetCustomAttribute. Every time one of these methods is called, it constructs new instances of the specified attribute type and sets each of the instance’s fields and properties based on the values specified in the code.
To test this, first let’s define a simple attribute:
public class BarAttribute : Attribute { public BarAttribute() { Now = DateTime.Now; } public DateTime Now { get; private set; } } [Bar] public class Foo { }
I capture the construction date in a property, which I can then assert on with a simple test:
[Test] public void AttrTester() { var attrs = typeof (Foo).GetCustomAttributes(typeof (BarAttribute), false); var first = (BarAttribute)attrs[0]; Thread.Sleep(1000); attrs = typeof (Foo).GetCustomAttributes(typeof (BarAttribute), false); var second = (BarAttribute)attrs[0]; first.ShouldNotBeTheSameAs(second); first.Now.ShouldNotEqual(second.Now); }
Sure enough, this test passes. Lesson for today: validate assumptions with a test.