为什么 ProvideAspect 方法在实例化属性时不将属性添加到 IL
本文关键字:属性 添加 IL 方法 实例化 为什么 ProvideAspect | 更新日期: 2023-09-27 18:34:10
我有以下代码用于我应用于类和类中的属性的属性:
public class SerialiseAttribute : Attribute, IAspectProvider, IValidableAnnotation {
public string ApplyToProperty { get; set; }
public string Name { get; set; }
public bool Ignore { get; set; }
bool IValidableAnnotation.CompileTimeValidate(object target) { return true; }
IEnumerable<AspectInstance> IAspectProvider.ProvideAspects(object targetElement) {
var type = targetElement as Type;
if (type != null && !FastSerialisationCacheAttribute.AppliedTo.Contains(type)) {
FastSerialisationCacheAttribute.AppliedTo.Add(type);
yield return new AspectInstance(type, new FastSerialisationCacheAttribute());
}
}
}
这将初始化 FastSerialisationCacheAttribute 并成功执行 CompileTimeInitialize(它派生自 TypeLevelAspect 方面)。 但是,当我检查生成的 IL 时;提供的类型上没有 FastSerialisationCacheAttribute,在运行时我也无法使用反射找到一个。
如果我使用以下代码切换提供程序方面函数:
IEnumerable<AspectInstance> IAspectProvider.ProvideAspects(object targetElement) {
var type = targetElement as Type;
if (type != null && !FastSerialisationCacheAttribute.AppliedTo.Contains(type)) {
FastSerialisationCacheAttribute.AppliedTo.Add(type);
var constructor = typeof(FastSerialisationCacheAttribute).GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null);
var objectConstruction = new ObjectConstruction(constructor);
var introduceCacheAspect = new CustomAttributeIntroductionAspect(objectConstruction);
yield return new AspectInstance(type, introduceCacheAspect);
}
}
然后,它将属性添加到 IL,但这不会初始化属性(执行 CompileTimeInitialize)。
好吧,我认为您的问题已经非常接近解决方案。如果要动态引入方面和属性,则需要从方法返回FastSerialisationCacheAttribute
和CustomAttributeIntroductionAspect
ProvideAspects
实例。
方法IAspectProvider.ProvideAspects
在从程序集读取所有先前应用的外观属性后执行。如果在第二个示例中引入另一个属性,那么它导致方面引入已经太晚了。
在IAspectProvider.ProvideAspects
您通常会为目标引入其他方面。如果您确实还需要引入实际属性,那么您可以使用 CustomAttributeIntroductionAspect
.
请注意,通常不需要添加属性即可使方面正常工作,但我不知道您的代码中的逻辑是什么。