Doesn't intercepting base method?

27 views
Skip to first unread message

veihan

unread,
Jan 21, 2015, 3:59:16 AM1/21/15
to castle-pro...@googlegroups.com
Hello

Probably this is a duplicate... but I will describe my problem anyway.

Lets say I have classes:

    public abstract class Foo
    {
        public virtual void DoSomething()
        {
            Console.WriteLine("Doing something base");
        }
    }

    public class Bar : Foo
    {
        public override void DoSomething()
        {
            Console.WriteLine("Doing something");
            base.DoSomething();
        }
    }

and interceptor:

    public class MyAspect : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            Console.WriteLine("Method is intercepted...");
            invocation.Proceed();
        }
    }

    public class MyInterceptorSelector : IModelInterceptorsSelector
    {
        public bool HasInterceptors(ComponentModel model)
        {
            return typeof(MyAspect) != model.Implementation &&
            model.Implementation.Namespace.StartsWith("Dp2");
        }

        public InterceptorReference[] SelectInterceptors(ComponentModel model, InterceptorReference[] interceptors)
        {
            var interceptorss = interceptors.ToList();
            interceptorss.Add(InterceptorReference.ForType<MyAspect>());
            return interceptorss.ToArray();
        }
    }

and registration:

    public class Bootstrapper
    {
        public Bootstrapper(IWindsorContainer container)
        {
            Container = container;
        }

        public IWindsorContainer Container { get; private set; }

        public void Run()
        {
            Container.Register(Component.For<MyAspect>());
            Container.Kernel.ProxyFactory.AddInterceptorSelector(new MyInterceptorSelector());
            Container.Register(Component.For<Foo>().ImplementedBy<Bar>());
        }
    }

in test:

    [TestFixture]
    public class UnitTest1
    {
        [Test]
        public void TestMethod1()
        {
            var bts = new Bootstrapper(new WindsorContainer());
            bts.Run();

            var bar = bts.Container.Resolve<Foo>();
            bar.DoSomething();
        }
    }

output is:

Method is intercepted...
Doing something
Doing something base

ergo interceptor hasn't been called on base method execution.

Is there a way to make this work?

Jonathon Rossi

unread,
Jan 21, 2015, 8:43:28 PM1/21/15
to Castle Project Users
Interceptors in Windsor are implemented by our DynamicProxy library, which works by creating a class (e.g. BarProxy) at runtime that inherits your class (e.g. Bar) and overrides its virtual methods, you can see this in the debugger or if you print out `bar.GetType().FullName`. When the overridden method is called it delegates off to your interceptor which must call Proceed otherwise the base method (i.e. Bar::DoSomething) isn't called. Below is a really simplified idea of what the runtime generated proxy class looks like:

    public class BarProxy : Bar
    {
        public override void DoSomething()
        {
            interceptor.Intercept(invocation);
        }
    }

It should now be clear the reason the interceptor isn't called for both Foo::DoSomething and Bar::DoSomething.

--
You received this message because you are subscribed to the Google Groups "Castle Project Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to castle-project-u...@googlegroups.com.
To post to this group, send email to castle-pro...@googlegroups.com.
Visit this group at http://groups.google.com/group/castle-project-users.
For more options, visit https://groups.google.com/d/optout.



--
Jono

veihan

unread,
Jan 22, 2015, 3:56:44 AM1/22/15
to castle-pro...@googlegroups.com
Ok I understand you. It can't by done with current dynamic proxy impl behind interceptor.

To unsubscribe from this group and stop receiving emails from it, send an email to castle-project-users+unsub...@googlegroups.com.

To post to this group, send email to castle-pro...@googlegroups.com.
Visit this group at http://groups.google.com/group/castle-project-users.
For more options, visit https://groups.google.com/d/optout.



--
Jono
Reply all
Reply to author
Forward
0 new messages