autofac / Autofac.Extras.DynamicProxy

Interceptor and decorator support for Autofac IoC via Castle DynamicProxy
MIT License
106 stars 33 forks source link

Calls to other methods within the same class are not being intercepted #50

Closed tskong closed 1 year ago

tskong commented 1 year ago

Describe the Bug

I've upgraded to the latest Autofac and the main project from .net 4.7.2 to .net core 6, and I''ve noticed a change in behaviour. With the old version, it used to intercept all methods to a class. e.g. If a method called another method within that class, both would be intercepted.

Is this a change in intended change of behaviour, or is this a bug?

Steps to Reproduce

Create asp.net core 6 MVC project.

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{
    builder.Register(c => new TestInterceptor());

    builder.RegisterType<Calculator>()
    .As<ICalculator>()
    .EnableInterfaceInterceptors()
    .InterceptedBy(typeof(TestInterceptor));
});

Then the Test Interceptor

    public class TestInterceptor : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            invocation.Proceed();
        }
    }

And finally the Controller method

        public HomeController(ICalculator calc)
        {
            _calc = calc;
            var a =_calc.Add(1, 2); // intercepted
            var b = _calc.Subtract(4, 2);   // intercepted
            var c = _calc.SomeMaths(10, 11); // intercepted, but not when SomeMaths() calls Add and Subtract

        }

Expected Behavior

For Add() and Subtract() to be intercepted when called from SomeMethod()

Exception with Stack Trace

n/a

Dependency Versions

<PackageReference Include="Autofac" Version="6.5.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Autofac.Extras.DynamicProxy" Version="6.0.1" />

Additional Info

n/a

tillig commented 1 year ago

All the work for interception is being done by Castle.Core; while Autofac will wire it up for you, be aware that the actual exectuion of the interceptors and how they function, the generation of the proxies, etc., is not Autofac.

I don't see anything in the history that would indicate why this behavior has changed for you. We've been referencing Castle.Core 4.4.0 since February 2020, prior to which we were referencing Castle.Core 4.3.1. I'm not sure what previous versions of the libraries you were using, but it may be that Castle changed the way they handle interception.

In all the cases where we generate the proxy, all we're doing is using default options unless you pass something in that overrides it - here's where interface proxies get created, here's where class proxies get created. As you can see, the magic is in Castle.Core, not Autofac. Scrolling back through history, it looks like we've been doing exactly this for six years or more, the code hasn't changed. (In Git blame you'll see it's been reformatted as we clean things up, but if you chase it back in time, it's been the same since the beginning.)

If you upgraded from Autofac.Extras.DynamicProxy pre-5.0.0 to now, that's where you'd see the change in Castle.Core version, and that'd be the answer to the question. If you started out with Autofac.Extras.DynamicProxy 5.0.0 or later, then I'm not sure what happened, but nothing here changed. Sorry.