按名称从 class 动态导入 postsharp 方面字段

Import postsharp aspect field from class by name dynamically

如果我有 class:

class MyClass
{
  IMyInterface _mi;

  [MyAspectAttribute("_mi")]
  bool _myValue;

  // ...
}

有没有办法创建方面属性 MyAspectAttribute 拦截获取和设置 (bool myValue) 的值并且还导入在属性 [MyAspectAttribute("_mi")] 中指定的字段,在这种情况下 _mi动态以便我可以在方面使用它? (我想在获取或设置方面的字段之前调用接口)。

我知道如何写方面我只是不知道如何动态导入指定的字段(在这个例子中是_mi)。所有示例都要求您知道要导入的确切字段名称(但我希望将名称传递到我的方面)。

谢谢。

您可以通过实现 IAdviceProvider.ProvideAdvices 方法并为要导入的字段返回 ImportLocationAdviceInstance 来动态导入字段。下面的示例方面演示了此技术。

[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()
    {
    }
}