如何在我的属性中设置动态值

时间:2011-07-12 13:46:36

标签: c# attributes

我想将动态变量作为参数传递给我的属性。在这里,我想使用Environment.MachineName,请参阅下面的代码:

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

但是我收到了这个错误: 错误1属性参数必须是属性参数类型Abc.ServiceBus.Monitoring.ViewModel

的常量表达式,typeof表达式或数组创建表达式

为了传递我的Environment.MachineName?

,是否有尽可能干净的解决方法?

感谢。

约翰

PS:我发现了一些关于这个案子的文章,但是它写得像2 - 3年前一样。但是今天,来自.NET 4.0的clr能提供一些很好的解决方案吗?

2 个答案:

答案 0 :(得分:10)

您可以使用特殊值创建枚举,并在属性的单独构造函数重载中接受它们:

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)]

答案 1 :(得分:10)

属性参数在编译时评估,而不是在运行时评估。所以它们必须是编译时间常数......

但是,您可以创建一个派生类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; } }
}