按名称从 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()
{
}
}
如果我有 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()
{
}
}