Как установить динамическое значение в моем атрибуте - PullRequest
8 голосов
/ 12 июля 2011

Я хотел бы передать динамическую переменную в качестве параметра моему атрибуту.Здесь я хочу использовать Environment.MachineName, см. Код ниже:

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

Но я получаю эту ошибку: Ошибка 1 Аргументом атрибута должно быть выражение константы, выражение typeof или выражение создания массива параметра атрибутаТип Abc.ServiceBus.Monitoring.ViewModel

Существует ли какой-либо обходной путь настолько чистым, насколько это возможно, чтобы передать мой Environment.MachineName?

Спасибо.

Джон

PS: Я нашел несколько статей, в которых рассказывается об этом деле, но оно было написано 2-3 года назад.Но сегодня дает ли clr, исходящий из .NET 4.0, хорошее решение?

Ответы [ 2 ]

10 голосов
/ 12 июля 2011

Параметры атрибутов оцениваются во время компиляции, а не во время выполнения.Поэтому они должны быть константами времени компиляции ...

Однако вы можете создать атрибут производного класса LocalMachineConfigurationKey, который принимает только один параметр и использует Environment.MachineName во время выполнения для оценки свойства.

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; } }
}
10 голосов
/ 12 июля 2011

Вы можете создать перечисление со специальными значениями и принять их в отдельной перегрузке конструктора в атрибуте:

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)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...