2010-02-19 19 views
11

Mam niestandardowy atrybut, wewnątrz konstruktora mojego niestandardowego atrybutu chcę ustawić wartość właściwości mojego atrybutu na typ właściwości, do której mój atrybut został zastosowany, czy jest jakiś sposób uzyskania dostępu do elementu, którego atrybut był zastosowane do wewnątrz mojej klasy atrybutów?Uzyskaj człon, do którego atrybutu zastosowano od wewnątrz konstruktora atrybutu?

+0

można krótko opisać przypadków użycia? – Tanmay

+1

Jeśli możesz podać więcej szczegółów na temat problemu, który rozwiązujesz, możliwe będzie dostarczenie alternatywnego rozwiązania. –

+1

Dzięki, wiem, w jaki sposób mogę osiągnąć to samo w inny sposób, ale chciałem wiedzieć, czy to było możliwe, ponieważ kod byłby czystszy. – ryudice

Odpowiedz

13

Atrybuty nie działają w ten sposób, obawiam się. Są jedynie "znacznikami", przyczepionymi do przedmiotów, ale nie mogącymi z nimi współdziałać.

Atrybuty powinny być zwykle pozbawione zachowania, zawierające po prostu meta-dane dla typu, do którego są przyłączone. Każde zachowanie powiązane z atrybutem powinno być dostarczane przez inną klasę, która szuka obecności atrybutu i wykonuje zadanie.

Jeśli jesteś zainteresowany typem, do którego stosowany jest atrybut, informacja ta będzie dostępna w tym samym czasie, w którym zastanawiasz się nad uzyskaniem atrybutu.

+0

Tak jak mówisz, nie jest to koniec świata, ponieważ znasz typ, kiedy zdobywasz atrybut niestandardowy za pomocą Reflection, ale byłoby to "miłe", gdyby typ przekazany do GetCustomAttribute był również przechowywany w System.Attribute –

0

Możesz zrobić dalej. To prosty przykład.

//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

Jest to możliwe z .NET 4.5 wykorzystaniem CallerMemberName:

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

Wtedy twój atrybut:

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