2010-02-19 3 views
11

J'ai un attribut personnalisé, dans le constructeur de mon attribut personnalisé Je veux définir la valeur d'une propriété de mon attribut sur le type de la propriété à laquelle mon attribut a été appliqué, est-il possible d'accéder au membre appliqué à partir de l'intérieur de ma classe d'attribut?Obtenir le membre à quel attribut a été appliqué à partir du constructeur d'attribut à l'intérieur?

+0

Pouvez-vous décrire brièvement le cas d'utilisation? – Tanmay

+1

Si vous pouvez fournir plus de détails sur le problème que vous résolvez, il pourrait être possible de fournir une solution alternative. –

+1

Merci, je sais comment je peux réaliser la même chose d'une manière différente, mais je voulais savoir si cela était possible parce que le code serait plus propre. – ryudice

Répondre

13

Les attributs ne fonctionnent pas comme ça, j'ai peur. Ils sont simplement des "marqueurs", attachés à des objets, mais incapables d'interagir avec eux.

Les attributs eux-mêmes doivent généralement être dépourvus de comportement, contenant simplement des méta-données pour le type auquel ils sont attachés. Tout comportement associé à un attribut doit être fourni par une autre classe qui recherche la présence de l'attribut et effectue une tâche.

Si vous êtes intéressé par le type auquel l'attribut est appliqué, cette information sera disponible en même temps que vous réfléchissez pour obtenir l'attribut.

+0

Comme vous le dites, ce n'est pas la fin du monde comme vous connaissez le type lors de l'obtention de l'attribut personnalisé via Reflection mais ce serait "bien" si le Type transmis à GetCustomAttribute était également stocké dans le System.Attribute –

0

Vous pouvez faire ensuite. C'est un exemple simple.

//target class 
public class SomeClass{ 

    [CustomRequired(ErrorMessage = "{0} is required", ProperytName = "DisplayName")] 
    public string Link { get; set; } 

    public string DisplayName { get; set; } 
} 
    //custom attribute 
    public class CustomRequiredAttribute : RequiredAttribute, IClientValidatable 
{ 
    public string ProperytName { get; set; } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     var propertyValue = "Value"; 
     var parentMetaData = ModelMetadataProviders.Current 
      .GetMetadataForProperties(context.Controller.ViewData.Model, context.Controller.ViewData.Model.GetType()); 
     var property = parentMetaData.FirstOrDefault(p => p.PropertyName == ProperytName); 
     if (property != null) 
      propertyValue = property.Model.ToString(); 

     yield return new ModelClientValidationRule 
     { 
      ErrorMessage = string.Format(ErrorMessage, propertyValue), 
      ValidationType = "required" 
     }; 
    } 
} 
0

Il est possible de 4,5 .NET en utilisant CallerMemberName:

[SomethingCustom] 
public string MyProperty { get; set; } 

Ensuite, votre attribut:

[AttributeUsage(AttributeTargets.Property)] 
public class SomethingCustomAttribute : Attribute 
{ 
    public StartupArgumentAttribute([CallerMemberName] string propName = null) 
    { 
     // propName = "MyProperty" 
    } 
} 
Questions connexes