如果使用自定义属性注入,本机 PostSharp 属性将被忽略
Native PostSharp attributes are ignored if injected using Custom Attributes
考虑以下代码:
[AttributeUsage(validOn: AttributeTargets.Property)]
public sealed class ExcludeAttribute : Attribute
{
}
[PSerializable]
public sealed class PsDependencyPropertyAttribute : TypeLevelAspect, IAspectProvider
{
public PsDependencyPropertyAttribute()
{
}
public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
{
var targetType = (Type)targetElement;
//---
var introduceObfuscationAspect =
new CustomAttributeIntroductionAspect(
new ObjectConstruction(constructor: typeof(ObfuscationAttribute).GetConstructor(types: Type.EmptyTypes)));
introduceObfuscationAspect.CustomAttribute.NamedArguments.Add(key: "Feature", value: "renaming");
introduceObfuscationAspect.CustomAttribute.NamedArguments.Add(key: "Exclude", value: true);
introduceObfuscationAspect.CustomAttribute.NamedArguments.Add(key: "StripAfterObfuscation", value: true);
// add a Obfuscation attribute to every relevant property
foreach (var property
in targetType.GetProperties(
bindingAttr: BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Instance)
.Where(
predicate: property =>
property.CanWrite &&
!property.IsDefined(attributeType: typeof(ExcludeAttribute), inherit: false)))
yield return new AspectInstance(targetElement: property, aspect: introduceObfuscationAspect);
//---
//! NATIVE PostSharp ATTRIBUTES DON'T GET PROCESSED IF THEY'RE INJECTED AT COMPILE TIME
var introduceDependencyPropertyAspect =
new CustomAttributeIntroductionAspect(
new ObjectConstruction(constructor: typeof(DependencyPropertyAttribute).GetConstructor(types: Type.EmptyTypes)));
// add a DependencyPropertyA attribute to every relevant property
foreach (var property
in targetType.GetProperties(
bindingAttr: BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance)
.Where(
predicate: property =>
property.CanWrite &&
!property.IsDefined(attributeType: typeof(ExcludeAttribute), inherit: false)))
yield return new AspectInstance(targetElement: property, aspect: introduceDependencyPropertyAspect);
}
}
使用此自定义属性确实会注入 2 个属性 [DependencyProperty, Obfuscation(Feature = "renaming", Exclude = true, StripAfterObfuscation = true)]
,唯一的问题是 DependencyProperty
是 PostSharp 属性,不会被处理,只是被注入。这是合理的,因为自定义属性告诉 PS 只注入这两个属性,但是有没有办法在使用自定义属性注入时处理 PS DependencyProperty
?
您可以直接提供 DependencyPropertyAttribute
作为目标 属性 的一个方面,而不是通过 CustomAttributeIntroductionAspect
。例如:
yield return new AspectInstance(targetElement: property, aspect: new DependencyPropertyAttribute());
这就是为什么 DependencyPropertyAttribute
在作为属性引入时不被处理的原因:
PostSharp 管道分几个阶段处理程序集。首先执行属性的处理,然后执行切面编织器。如果任何方面在此阶段发出新的自定义属性,PostSharp 将不再处理该属性,因为属性处理阶段已经完成。
考虑以下代码:
[AttributeUsage(validOn: AttributeTargets.Property)]
public sealed class ExcludeAttribute : Attribute
{
}
[PSerializable]
public sealed class PsDependencyPropertyAttribute : TypeLevelAspect, IAspectProvider
{
public PsDependencyPropertyAttribute()
{
}
public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
{
var targetType = (Type)targetElement;
//---
var introduceObfuscationAspect =
new CustomAttributeIntroductionAspect(
new ObjectConstruction(constructor: typeof(ObfuscationAttribute).GetConstructor(types: Type.EmptyTypes)));
introduceObfuscationAspect.CustomAttribute.NamedArguments.Add(key: "Feature", value: "renaming");
introduceObfuscationAspect.CustomAttribute.NamedArguments.Add(key: "Exclude", value: true);
introduceObfuscationAspect.CustomAttribute.NamedArguments.Add(key: "StripAfterObfuscation", value: true);
// add a Obfuscation attribute to every relevant property
foreach (var property
in targetType.GetProperties(
bindingAttr: BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Instance)
.Where(
predicate: property =>
property.CanWrite &&
!property.IsDefined(attributeType: typeof(ExcludeAttribute), inherit: false)))
yield return new AspectInstance(targetElement: property, aspect: introduceObfuscationAspect);
//---
//! NATIVE PostSharp ATTRIBUTES DON'T GET PROCESSED IF THEY'RE INJECTED AT COMPILE TIME
var introduceDependencyPropertyAspect =
new CustomAttributeIntroductionAspect(
new ObjectConstruction(constructor: typeof(DependencyPropertyAttribute).GetConstructor(types: Type.EmptyTypes)));
// add a DependencyPropertyA attribute to every relevant property
foreach (var property
in targetType.GetProperties(
bindingAttr: BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance)
.Where(
predicate: property =>
property.CanWrite &&
!property.IsDefined(attributeType: typeof(ExcludeAttribute), inherit: false)))
yield return new AspectInstance(targetElement: property, aspect: introduceDependencyPropertyAspect);
}
}
使用此自定义属性确实会注入 2 个属性 [DependencyProperty, Obfuscation(Feature = "renaming", Exclude = true, StripAfterObfuscation = true)]
,唯一的问题是 DependencyProperty
是 PostSharp 属性,不会被处理,只是被注入。这是合理的,因为自定义属性告诉 PS 只注入这两个属性,但是有没有办法在使用自定义属性注入时处理 PS DependencyProperty
?
您可以直接提供 DependencyPropertyAttribute
作为目标 属性 的一个方面,而不是通过 CustomAttributeIntroductionAspect
。例如:
yield return new AspectInstance(targetElement: property, aspect: new DependencyPropertyAttribute());
这就是为什么 DependencyPropertyAttribute
在作为属性引入时不被处理的原因:
PostSharp 管道分几个阶段处理程序集。首先执行属性的处理,然后执行切面编织器。如果任何方面在此阶段发出新的自定义属性,PostSharp 将不再处理该属性,因为属性处理阶段已经完成。