【问题标题】:Native PostSharp attributes are ignored if injected using Custom Attributes如果使用自定义属性注入本机 PostSharp 属性将被忽略
【发布时间】:2018-08-17 23:57:03
【问题描述】:

考虑以下代码:

 [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);
    }
}

使用这个自定义属性确实注入了两个属性[DependencyProperty, Obfuscation(Feature = "renaming", Exclude = true, StripAfterObfuscation = true)],唯一的问题是DependencyProperty 是一个PostSharp 属性并且没有得到处理,只是注入了。这是合理的,因为自定义属性告诉 PS 只注入这 2 个属性,但是有没有办法在使用自定义属性注入 PS DependencyProperty 时对其进行处理?

【问题讨论】:

    标签: c# attributes aop postsharp


    【解决方案1】:

    您可以直接提供DependencyPropertyAttribute 作为目标属性的一个方面,而不是通过CustomAttributeIntroductionAspect。例如:

    yield return new AspectInstance(targetElement: property, aspect: new DependencyPropertyAttribute());
    

    这就是DependencyPropertyAttribute 在作为属性引入时不被处理的原因:

    PostSharp 管道分几个阶段处理程序集。首先执行属性的处理,然后执行方面编织器。如果任何方面在此阶段发出新的自定义属性,则 PostSharp 将不再处理该属性,因为属性处理阶段已经完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-13
      • 1970-01-01
      • 2015-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-18
      相关资源
      最近更新 更多