How to set dynamic value in my Attribute
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 ?
Solution 1:
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)]
Solution 2:
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; } }
}