2011-07-12 14 views
6

Me gustaría pasar una variable dinámica como parámetro a mi atributo. Aquí quiero usar Environment.MachineName, ver el código de abajo:Cómo establecer el valor dinámico en mi Atributo

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

Pero me sale este error: Error 1 Un argumento atributo debe ser una expresión constante, typeof expresión o la creación de la matriz expresión de un tipo de parámetro de atributo Abc.ServiceBus.Monitoring.ViewModel

¿Hay alguna solución lo más limpia posible para pasar mi Environment.MachineName?

Gracias.

John

PD: He encontrado algunos artículos que hablan sobre este caso, pero haber sido escrito como hace 2-3 años. Pero hoy, ¿el clr que viene de .NET 4.0 ofrece alguna buena solución?

Respuesta

9

Se puede crear una enumeración con valores especiales, y aceptarlos en una sobrecarga del constructor independiente en el atributo:

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

parámetros de atributos se evalúan en tiempo de compilación, no en tiempo de ejecución. Por lo tanto, deben ser constantes de tiempo de compilación ...

Sin embargo, puede crear un atributo de clase derivada LocalMachineConfigurationKey que solo tome un parámetro y use Environment.MachineName en tiempo de ejecución para evaluar la propiedad.

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; } } 
} 
+0

1+ para las constantes de tiempo de compilación – SimonGates

Cuestiones relacionadas