Question

What kind of things have you used custom .NET attributes for in the real world?

I've read several articles about them, but I have never used custom attributes.

I feel like I might be overlooking them when they could be useful.

I am talking about attributes that you create, not ones that are already included in the framework.

Was it helpful?

Solution

I've used them "custom" attributes for validation (ie. marking a field to be validated with my own "credit card validation") and custom LinqToLucene analyzers I've written (ie. specifying which analyzer to use on a given field).

The validation code, for example, would look something like this:

public class Customer
{
     [CreditCardValidator]
     string creditCardNumber;

     [AddressValidator]
     string addressLineOne
}

When the object above is validated, each field is validated with the appropriate validator thanks to the "custom" attribute.

In the LinqToLucene stuff I've written custom attributes are nice because they allow you to find (through reflection) specific fields at run time. For example, if you have a customer object, you may be interested in getting all the properties that have been marked as "index me": a custom attribute lets you do this easily since it exposes meta-data about the object in a manner that is easy to query.

OTHER TIPS

I created a scripting engine, and tagged various methods with the [Command] attribute. This meant that these functions were exposed to the scripting engine.

Example:

[Command(HelpText = "Lists active users")]
void ListUsers(void)
{

}

[Command(HelpText = "Terminate a specific user's connection")]
void EndConnection(int userID)
{

}

And as used:

MyScriptEngine>>  Help
Available Commands are:
    ListUsers: Lists active users
    EndConnection {userID}: Terminate a specific user's connection

MyScriptEngine>> EndConnection 3
    User 3 (Michael) has had his connection terminated.

MyScriptEngine>>

Among other things, I've used them to specify EBNF which is read at run-time to create custom parsers on the fly and also to specify metadata about fields for a database.

I find one 'pattern' I'm commonly using custom attributes is to replace enums especially when there is a dependency on the enum in diff places in code.

E.g. I might have an enum for a state of an object. Based on this state, I have maybe 3 or 4 different places in code which I would do a 'switch' of that enum and perform some operation. Some other developer could easily introduce a bug by adding a new enum but not handling in one of the switch statements somewhere else in code.

So to avoid this I create a custom attributes declared to a static class. The custom attributes are loaded in the static constructor of the class into a dictionary and all places in code use the dictionary instead of switch statements. The custom attribute constructor contains the 'hard-coded' values for each switch statement.

I had to serialize some objects to a custom (legacy) format, and I used attributes to identify which fields should be serialized and how to format them. Then I had a serializer that could take any object with these attributes and use reflection to format it.

I haven't really found a use for custom attributes as of yet. There have been a few situations where I thaught they may be appropriate but didn't use them because apparently the reflection involved in reading custom attributes is quite expensive.

I have placed custom attributes on classes within "plug-in" DLLs. This allows a framework to dynamically discover available plug-ins, evaluate whether they are of interest, and then dynamically load the ones of interest.

In our domain, the example is plug-ins which model particular vehicles within a family. One plug-in for a vehicle family might actually model several vehicle models within the vehicle family (e.g., "MX-6", "Probe"). If an ID or Model Name is included as a custom attribute array, we can quickly ignore any DLLs that don't even have custom attributes, and then further ignore any that do not model the vehicle of interest.

I had used it in one of the ORM frameworks which I developed based on the ActiveRecord pattern. This is the same kind of implementation that is available in LINQ, Castle project etc.

The framework was called "SkyFramework", but it was not opensource.

for e.g. Just a rough example...

You will find similar examples in other opensource projects as well.

[Sky.Table ("user")]
public class User
{
    [Sky.Column ("username")]
    public string UserName;

    [Sky.Column ("pwd")]
    public string Password;
}

NOTE: The attribute "Table", "Columns" were the custom attributes at that time.

The ActiveRecord engine parses the object for these attributes and generates the respective functions for CRUD... etc...

Similarly, I had developed some custom attributes for identifying portions of code that needs to be benchmarked...for e.g..

[Sky.BenchMark()]
public void LongRunningMethod(..)
{
}

The methods marked with the above attributes are automatically bench marked and a log is generated. These were some earlier implementations.

There's an Apress book available on the topic.. Applied .NET Attribues which may be of help to you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top