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 ?
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.
For example, the Standard attributes that can be used as dynamic attributes include Text Relevance (sorting. text-relevance) and Predictive Sort (sorting. predictive-sort).
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)]
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; } }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With