Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set dynamic value in my Attribute

Tags:

c#

attributes

I would like to pass a dynamic variable as a parameter to my attribute. Here I want to use Environment.MachineName, see the code below:

public interface IMonitoringViewModelConfiguration : IConfigurationContainer
{
    [ConfigurationKey("MonitoringService", Environment.MachineName)]
    string ConnectionString { get; }
}

But I get this error: Error 1 An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type Abc.ServiceBus.Monitoring.ViewModel

Is there any workaround as clean as possible in order to pass my Environment.MachineName ?

Thanks.

John

PS: I've found some articles which talk about this case but it have been written like 2-3 years ago. But today, does the clr which comes from .NET 4.0 gives some nice solution ?

like image 493
John Avatar asked Jul 12 '11 13:07

John


People also ask

How do I create a dynamic attribute?

Define the Dynamic Attribute in the items. xml file, create new ClientName type with two attributes, which persistence type is set to property . Their values are persisted in the database. Create an attribute that can compute its value in the memory by using values from persisted attributes and return the result.

Which of these attributes can you use to create a dynamic attribute?

For example, the Standard attributes that can be used as dynamic attributes include Text Relevance (sorting. text-relevance) and Predictive Sort (sorting. predictive-sort).


2 Answers

You could create an enum with special values, and accept them in a separate constructor overload in the attribute:

enum SpecialConfigurationValues
{
    MachineName
    // , other special ones
}

class ConfigurationKeyAttribute : Attribute
{
    private string _key;
    private string _value;

    public ConfigurationKeyAttribute(string key, string value)
    {
        // ...
    }

    public ConfigurationKeyAttribute(string key, SpecialConfigurationValues specialValue)
    {
        _key = key;
        switch (specialValue)
        {
            case SpecialConfigurationValues.MachineName:
                _value = Environment.MachineName;
                break;
            // case <other special ones>
        }
    }
}

[ConfigurationKey("MonitoringService", SpecialConfigurationValues.MachineName)]
like image 151
C.Evenhuis Avatar answered Sep 20 '22 13:09

C.Evenhuis


Attribute parameters are evaluated at compile time, not at runtime. So they have to be compile time constants...

However, you could create a derived class LocalMachineConfigurationKey attribute that takes only one parameter and uses Environment.MachineName at runtime to evaluate the property.

public class ConfigurationKeyAttribute : Attribute
{
    private readonly string _key;
    private readonly string _machineName;

    public ConfigurationKeyAttribute(string key, string machineName)
    {
        _key = key;
        _machineName = machineName;
    }

    protected ConfigurationKeyAttribute(string key) : this(key, null)
    {
    }

    public string Key { get { return _key; } }
    public virtual string MachineName { get { return _machineName; } }
}

public class LocalMachineConfigurationKeyAttribute : ConfigurationKeyAttribute
{
    public LocalMachineConfigurationKeyAttribute(string key) : base(key)
    {
    }

    public override string MachineName { get { return Environment.MachineName; } }
}
like image 20
Thomas Levesque Avatar answered Sep 21 '22 13:09

Thomas Levesque