2017-08-31 1 views
1

Si j'ai une classe:importation champ aspect PostSharp de la classe par son nom dynamique

class MyClass 
{ 
    IMyInterface _mi; 

    [MyAspectAttribute("_mi")] 
    bool _myValue; 

    // ... 
} 

Y at-il un moyen de créer un aspect d'attribut MyAspectAttribute interceptant obtenir et définir la valeur (bool maValeur) et aussi les importations le champ qui est spécifié dans l'attribut [MyAspectAttribute ("_ mi")] dans ce cas _mi dynamiquement afin que je puisse l'utiliser dans l'aspect? (Je veux appeler l'interface avant d'obtenir ou de définir le champ dans l'aspect).

Je sais écrire l'aspect que je ne sais pas comment importer dynamiquement le champ spécifié (dans cet exemple _mi). Tous les exemples nécessitent que vous connaissiez le nom de champ exact à importer (mais je veux que le nom soit transmis à mon aspect).

Merci.

Répondre

0

Vous pouvez importer le champ dynamiquement en implémentant la méthode IAdviceProvider.ProvideAdvices et en renvoyant ImportLocationAdviceInstance pour le champ que vous souhaitez importer. L'aspect de l'échantillon ci-dessous démontre cette technique.

[PSerializable] 
public class MyAspectAttribute : LocationLevelAspect, IAdviceProvider, IInstanceScopedAspect 
{ 
    private string _importedFieldName; 

    public MyAspectAttribute(string importedFieldName) 
    { 
     _importedFieldName = importedFieldName; 
    } 

    public ILocationBinding ImportedField; 

    public IEnumerable<AdviceInstance> ProvideAdvices(object targetElement) 
    { 
     var target = (LocationInfo) targetElement; 
     var importedField = target.DeclaringType 
      .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) 
      .First(f => f.Name == this._importedFieldName); 

     yield return new ImportLocationAdviceInstance(
      typeof(MyAspectAttribute).GetField("ImportedField"), 
      new LocationInfo(importedField)); 
    } 

    [OnLocationGetValueAdvice, SelfPointcut] 
    public void OnGetValue(LocationInterceptionArgs args) 
    { 
     IMyInterface mi = (IMyInterface)this.ImportedField.GetValue(args.Instance); 
     mi.SomeMethod(); 

     args.ProceedGetValue(); 
    } 

    [OnLocationSetValueAdvice(Master = "OnGetValue"), SelfPointcut] 
    public void OnSetValue(LocationInterceptionArgs args) 
    { 
     IMyInterface mi = (IMyInterface) this.ImportedField.GetValue(args.Instance); 
     mi.SomeMethod(); 

     args.ProceedSetValue(); 
    } 

    public object CreateInstance(AdviceArgs adviceArgs) 
    { 
     return this.MemberwiseClone(); 
    } 

    public void RuntimeInitializeInstance() 
    { 
    } 
}