Executing aspect on base class method when derived class is decorated

dokonov's Avatar

dokonov

21 Oct, 2017 01:19 AM

Is it possible to have aspect executed on method of base class when derived class is decorated?
Like this:

    [AspectForDerived]
    public class DerivedClass : BaseClass
    {
        public void MethodInDerived()
        {
            Console.WriteLine("MethodInDerived called");
        }
    }
    
    public class BaseClass
    {
        public virtual void MethodInBase()
        {
            Console.WriteLine("MethodInBase called");
        }
    }

    [Serializable]
    public class AspectForDerived : OnMethodBoundaryAspect
    {
        public override void OnEntry(MethodExecutionArgs args)
        {
            Console.WriteLine($"AspectForDerived; args.Method.MemberType: [{args.Method.MemberType}]");
            base.OnEntry(args);
        }
    }

So when this is called:
        [Test]
        public void RunMethodInBase()
        {
            var derivedClass = new DerivedClass();
            derivedClass.MethodInBase();
        }

we have it executed only on constructor of derived: "AspectForDerived; args.Method.MemberType: [Constructor]",
but we need access to method in base (parameters e.t.c.).

Thanks,
Dmitry

  1. Support Staff 1 Posted by PostSharp Techn... on 25 Oct, 2017 07:55 AM

    PostSharp Technologies's Avatar

    Hello,

    It means, that the desired output of the test is:

    AspectForDerived; args.Method.MemberType: [Constructor]
    AspectForDerived; args.Method.MemberType: [Method]
    MethodInBase called
    

    Is that right?

    PostSharp cannot decorate a base class method just for a specific derived class, it would be very dangerous. Neither OnMethodBoundaryAspect nor MethodInterceptionAspect don't intercept call sites itself in most cases. They modify a decorated method instead.

    If PostSharp would add your aspect on a base class method, then all other derived class would be affected, which is something you don't usually want.

    If you want force PostSharp to decorate a base class method just for a specific derived class, you can override the method:

        [AspectForDerived]
        public class DerivedClass : BaseClass
        {
            public override void MethodInBase()
            {
                base.MethodInBase();
            }
    
            public void MethodInDerived()
            {
                Console.WriteLine("MethodInDerived called");
            }
        }
    

    Or if you don't mind to affect the method in the base class (e.g. for tracing), you can decorate it directly:

        public class BaseClass
        {
            [AspectForDerived]
            public virtual void MethodInBase()
            {
                Console.WriteLine("MethodInBase called");
            }
        }
    

    Best regards,
    -jakub

  2. 2 Posted by dokonov on 25 Oct, 2017 05:46 PM

    dokonov's Avatar

    Thank you Jakub,

    Yes, desired output you mentioned is correct.

    I see, because aspects are instantiated in compile time PostSharp cannot do this for base method of specific derived type only. It would need reflection to sniff thru type hierarchy at run-time. Makes sense.

    Cheers,
    Dmitry

  3. Support Staff 3 Posted by PostSharp Techn... on 26 Oct, 2017 08:25 AM

    PostSharp Technologies's Avatar

    Hello,

    We are going to close this request as we believe it was solved. Please feel free to reopen the discussion if you need more help.

    Best regards,
    PostSharp team

  4. PostSharp Technologies closed this discussion on 26 Oct, 2017 08:25 AM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac