PostSharp Class-Aspect для добавления аспектов ко всем членам класса - PullRequest
0 голосов
/ 19 ноября 2018

Есть ли способ пометить класс атрибутом, который добавит атрибуты ко всем методам?

Например:

[TestAspect]
public class Test
{
    public void foo() { ... };

    [AttributeA]
    public void bar() { ... };
}

Теперь TestAspect должен сделать так, чтобыАспекты добавляются в bar ().

При написании класса AspectProvider, следующие должны применять AspectA и AspectB ко всем методам класса, которые имеют AttributeA.

[Serializable, AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class TestAspect : TypeLevelAspect, IAspectProvider
{
    private static readonly CustomAttributeIntroductionAspect aspectA =
     new CustomAttributeIntroductionAspect(
        new ObjectConstruction(typeof(AspectB).GetConstructor(Type.EmptyTypes)));

    private static readonly CustomAttributeIntroductionAspect aspectB =
    new CustomAttributeIntroductionAspect(
        new ObjectConstruction(typeof(AspectA).GetConstructor(Type.EmptyTypes)));

    public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
    {
        Type targetClassType = (Type)targetElement;

        foreach(MethodInfo methodInfo in targetClassType.GetMethods())
        {
            if(!methodInfo.IsDefined(typeof(AttributeA), false))
            {
                yield break;
            }
            yield return new AspectInstance(targetElement, aspectA);
            yield return new AspectInstance(targetElement, aspectB);
    }
}

Но, к сожалению, атрибуты не применяются к методам?Никаких исключений или ошибок не выдается.

У кого-нибудь есть совет?

1 Ответ

0 голосов
/ 18 декабря 2018

С помощью следующего кода я смог по крайней мере добавить 1 пользовательский атрибут к методам, которые отмечены AttributeA в моем классе, который отмечен TestClass.

[Serializable, AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public class TestClassAttribute : TypeLevelAspect, IAspectProvider
{

    public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
    {
        Type type = (Type)targetElement;

        return type.GetMethods().Where(method => method.GetCustomAttributes(typeof(AttributeA), false)
                .Any()).Select(m => new AspectInstance(m, new CustomAttributeIntroductionAspect(
                    new ObjectConstruction(typeof(AttributeB).GetConstructor(Type.EmptyTypes)))));
    }
}
...