Autofac.Extras.DynamicProxy icon indicating copy to clipboard operation
Autofac.Extras.DynamicProxy copied to clipboard

EnableClassInterceptors does not take into account KeyFilter-ed parameters in the constructor

Open elgatov opened this issue 1 year ago • 4 comments

Describe the Bug

When using EnableClassInterceptors() and registering a class with WithAttributeFiltering(), parameters decorated with KeyFilter will not have their filter taken into account when trying to intercept the class

Steps to Reproduce

using Autofac;
using Autofac.Extras.DynamicProxy;
using Autofac.Features.AttributeFilters;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Pruebas
{
    [TestClass]
    public class TestClassWithKeyedAttributeConstructor
    {
        enum TestEnum { STRING_ONE }
        public class ClassWithKeyedAttributeConstructor
        {
            private readonly string str;

            public ClassWithKeyedAttributeConstructor([KeyFilter(TestEnum.STRING_ONE)] string str) => this.str = str;

            public string GetStr() => str;
        }
        [TestMethod]
        public void TestClassWithKeyedAttributeConstructorCannotBeIntercepted()
        {
            var builder = new ContainerBuilder();
            builder.Register(c => "Hello").Keyed<string>(TestEnum.STRING_ONE);
            builder.Register(c => "World");
            //builder.RegisterType<ClassWithKeyedAttributeConstructor>().WithAttributeFiltering();
            builder.RegisterType<ClassWithKeyedAttributeConstructor>().WithAttributeFiltering().EnableClassInterceptors();
            var container = builder.Build();

            using var scope = container.BeginLifetimeScope();
            Assert.AreEqual("Hello", scope.Resolve<ClassWithKeyedAttributeConstructor>().GetStr());
        }
    }
}

Expected Behavior

Exception with Stack Trace

  Message: 
Assert.AreEqual failed. Expected:<Hello>. Actual:<World>. 

  Stack Trace: 
TestClassWithKeyedAttributeConstructor.TestClassWithKeyedAttributeConstructorCannotBeIntercepted() line 32

Dependency Versions

Autofac: 8.1.1 Autofac.Extras.DynamicProxy: 7.1.0 MSTest: 3.6.2

Additional Info

If we uncomment line 26 and comment line 27. The test will execute correctly.

elgatov avatar Nov 09 '24 17:11 elgatov

I just wanted to jump in and say that your issue here has been seen but it may be a bit before someone can jump in and do anything about it. We're dreadfully short on PRs coming in and there are only a couple of active maintainers, both of whom are doing this in their shrinking spare time. If you want this solved faster, we'd very much welcome a PR that includes the fix and a test to validate the fix.

My initial guess is that when the proxy is generated for the interceptor that we're not copying the attributes from the original class constructor parameters over to the interceptor constructor parameters. Is that right? Is there something else? I don't know without diving in and just solving the problem, which I don't have time for at this exact moment. But if you were going to try for a PR, that'd be a good place to start looking.

tillig avatar Nov 14 '24 00:11 tillig

Hi tillig,

I understand this is a side project and time is tight. I will try to check what you are pointing me too and see if I can fix it and get a PR, but as of right now I feel it is above my knowledge of c#.

Thanks for the help

elgatov avatar Nov 14 '24 13:11 elgatov

I believe the error is exactly in https://github.com/autofac/Autofac.Extras.DynamicProxy/blob/2115f37e00614fa0507ad5dae984622558a6dc0f/src/Autofac.Extras.DynamicProxy/RegistrationExtensions.cs#L130

for each PositionalParameter it is trying to resolve the service without taking into account if it's keyed. Tell me if you believe this is indeed the problem to pursue it further.

Thank you.

elgatov avatar Nov 18 '24 21:11 elgatov

I think that's a reasonable place to start, for sure.

tillig avatar Nov 18 '24 21:11 tillig