I am not sure if it is possible I have seen:
Change Attribute\'s parameter at runtime.
My case is very similar but I am trying to change the attribute of a class in
You need to code your attribute so that it supports runtime values. For example, the validation attributes support Internationalization of messages through the setting of a resource type and resource string as opposed to the static Message string.
Another approach is to use a IOC container such as StructureMap or Unity to provide some object/service that provides the values.
If you don;t want to couple your attribute to a particular container, use the Common ServiceLocator wrapper provided by the Patterns and Practices group.
If you use reflection, then not quite like this - reflection attributes can't be substituted - only the component-model view is impacted by TypeDescriptor
. However, you can subclass CategoryAttribute
to your purposes. Especially useful for i18n.
using System.ComponentModel;
using System;
[MyCategory("Fred")]
class Foo { }
static class Program
{
static void Main()
{
var ca = (CategoryAttribute)Attribute.GetCustomAttribute(typeof(Foo), typeof(CategoryAttribute));
Console.WriteLine(ca.Category);
// ^^^ writes "I was Fred, but not I'm EVIL Fred"
}
}
class MyCategoryAttribute : CategoryAttribute
{
public MyCategoryAttribute(string category) : base(category) { }
protected override string GetLocalizedString(string value)
{
return "I was " + value + ", but not I'm EVIL " + value;
}
}
Avoiding reflection entirely, you can do this via TypeDescriptor
:
using System;
using System.ComponentModel;
using System.Linq;
[Category("nice")]
class Foo { }
static class Program
{
static void Main()
{
var ca = TypeDescriptor.GetAttributes(typeof(Foo))
.OfType<CategoryAttribute>().FirstOrDefault();
Console.WriteLine(ca.Category); // <=== nice
TypeDescriptor.AddAttributes(typeof(Foo),new CategoryAttribute("naughty"));
ca = TypeDescriptor.GetAttributes(typeof(Foo))
.OfType<CategoryAttribute>().FirstOrDefault();
Console.WriteLine(ca.Category); // <=== naughty
}
}