views:

729

answers:

8

What are some cool applications for custom attributes in CLR/C# code that you've done or heard about? Also interesting new uses of the standard attributes is also ok!

Edit: Since Java's annotations seems to be the same as CLR's attrbutes, uses of Java annotations is also valid.

+8  A: 

And some core ones that are often overlooked:

Marc Gravell
Darn, you beat me to it!
Dmitri Nesteruk
+1 for the PrincipalPermissionAttribute - I can't believe i did this manually before.
Botz3000
+8  A: 

While not strictly C#, I've found an interesting use of Java annotations (= C# attributes) for marking student's assignments. Every semester I program a marking robot for students, and it turns out that first-year students for some reason don't seem to be able to follow instructions precisely, which of course causes the marking robot to fail. So what I do is go through their code, find all the methods that didn't meet the specification and fix them. Then I put an annotation (=attribute) onto each of the methods that were wrong, telling the marking robot to mark them down. It's probably the most simple and direct way to do this I think.

Ray Hidayat
Having to manually fix each student's code doesn't seem simple, though?
Dean J
True, but in our case it was simple because we had a policy where if a student's work didn't compile, it wasn't marked. So all I did was remove the method and replace it with a stub.
Ray Hidayat
+1  A: 

I have a case, where I want to present the actual implementation of an interface as data as well. This can be done via Reflection of course, but by using a specific attribute on the members I want to expose as data, I can encapsulate the work needed to do this.

The end result is that I create my implementation, decorate the desired members and then I can query the members through both code and data without having to do the Reflection code in each case.

Brian Rasmussen
+1  A: 

Sometimes, I use attributes to decorate classes or methods and use reflection to get the 'attributed' data.

Maybe a bit difficult to explain, but the last thing for which I've used attributes, is in a system where I have a couple of entities in a database.

Each entity has some kind of 'code', and each entity can also have some interpretation rules.

In my project, I have one entity class, which represents an entity that exists in the Database, and, I also have a set of 'Rule' classes. One Rule class contains the interpretation logic of a given entity.

In order to 'link' a certain 'Rule' (interpretation) to a specific instance of my entity, I've created a custom Attribute.

I decorate my 'Rule' class with this attribute, and through the attribute, I define for which entity this is a Rule. Then, when I load an entity from the DB, I inject the correct rule into that entity.

A little bit of code to make things clear:

public class MyEntity
{
    public string Code
    {
       get;
       private set;
    }

    public bool IsValidFor( ... )
    {
        IRule rule = RuleRegistry.GetRuleFor(this);

        if( rule.IsValid() ) ...
    }

}

[RuleAttrib("100")]
public class MyRule : IRule
{
    public bool IsValid()
    {
    }
}

This is just a little example, but I think you'll catch the drift.

The RuleAttrib attribute on the MyRule class, says that this is a Rule that should be applied to the instance of MyClass which has a code "100".

The RuleRegistry instance is able to retrieve the correct IRule for the current Entity (using reflection).

Another example in where I've used attributes, in combination with Postsharp, is the implementation of a 'locking' system: http://fgheysels.blogspot.com/2008/08/locking-system-with-aspect-oriented.html

Frederik Gheysels
Interesting idea there
Robert Gould
+1  A: 

we use custom java annotations to mark special purposes of certain methods, mostly targeted at developers:

  • @ScriptingAPI -- marks code that is exposed as part of our scripting API (warns developers that changes could affect the public API)
  • @Transaction -- marks methods on the database facade that are starting/commiting a transaction (we have a dedicated transaction handler class that respects this annotation)
  • @NeedsAttentionToSupportFoo -- if we know that feature Foo is a requirement that we will need to address in the near future, we use an annotation to mark code that we will need to touch to support it, i.e. when we come across a piece of code that makes us think "ah, this will need to be changed to support Foo", we annotate it. if the implementation of Foo is postponed or will never happen, it's easier to remove the annotation than to revert pre-mature optimizations scattered all around in the code.

another good example usage of a custom annotation is covered in this java specialist newsletter: enforcing a public no-args constructor in all sub classes.

netzwerg
+3  A: 

Check out xUnit and see how attributes are used to mark unit tests for expected behavior as well as feed data into tests. Attributes are used in a more meaningful manner than MSTest or NUnit.

From Samples\TestMethodExtensibility\Example.cs:

public class Example
{
    static int val;

    [RepeatTest(5, Timeout=250)]
    public void RepeatingTestMethod()
    {
        Thread.Sleep(100);
        Assert.Equal(2, 2);

        if (val == 0)
        {
            val++;
            Thread.Sleep(1000);
        }
    }
}

From test.xunit.extensions\DataTheories\TheoryAttributeTests.cs:

internal class TestMethodCommandClass
{
    public static IEnumerable<object[]> EmptyData
    {
        get { return new object[0][]; }
    }

    public static IEnumerable<object[]> NullData
    {
        get { return null; }
    }

    public static IEnumerable<object[]> TheoryDataProperty
    {
        get { yield return new object[] { 2 }; }
    }

    [Theory, PropertyData("EmptyData")]
    public void EmptyDataTheory() { }

    [Theory, PropertyData("NullData")]
    public void NullDataTheory() { }

    [Theory, OleDbData(
        @"Provider=Microsoft.Jet.OleDb.4.0; Data Source=DataTheories\UnitTestData.xls; Extended Properties=Excel 8.0",
        "SELECT x, y, z FROM Data")]
    public void TestViaOleDb(double x,
                             string y,
                             string z) { }

    [Theory, PropertyData("TheoryDataProperty")]
    public void TestViaProperty(int x) { }

    [Theory, ExcelData(@"DataTheories\UnitTestData.xls", "SELECT x, y, z FROM Data")]
    public void TestViaXls(double x,
                           string y,
                           string z) { }

}

For details see:

http://www.codeplex.com/xunit

Ants
Ah yes, this is what I consider to be one of the most appropriate uses of annotations.
Ray Hidayat
+2  A: 

nunit of course

the usages of attributes has been prided by kent beck:

NUnit 2.0 is an excellent example of idiomatic design. Most folks who port xUnit just transliterate the Smalltalk or Java version. That's what we did with NUnit at first, too. This new version is NUnit as it would have been done had it been done in C# to begin with.

source: http://www.nunit.org/

+1  A: 

Castle's ActiveRecord uses attributes. It hides some of the set-up complexity of NHibernate by decorating your Model objects with attributes indicating classes and fields that should be persisted to the database (and how). There is also use of attributes within the validation component to add model-based validation into ActiveRecord and the Monorail stack.

nocache