Search code examples
autofackeyfilter

Key Filter Constructor Usage Autofac Issue


I am trying to achieve Resolving instances using Autofac KeyFilter. I am getting results if explicitly resolve the instances using ResolveKeyed<> . However when using KeyFilter in Constructor i am seeing different instances being resolved as parameters.

here is the small example .. i came up..

public enum TestApiEnum
{
    TestA,
    TestB
}
public interface ITestService
{   
}
public interface ITestApi
{
}
public class TestService : ITestService
{
    public TestService([KeyFilter(TestApiEnum.TestA)]ITestApi testApiA, 
    [KeyFilter(TestApiEnum.TestB)] ITestApi testApiB)
    {       
    }
}
public class TestApiA : ITestApi
{
    public TestApiA(TestApiEnum testEnum)
    {
        TestApiEnum = testEnum;
    }
    public TestApiEnum TestApiEnum { get; set; }  
}

public class TestApiB: ITestApi
{
    public TestApiB(TestApiEnum testEnum)
    {
        TestApiEnum = testEnum;
    }
    public TestApiEnum TestApiEnum { get; set; }
}

Builder Registration

       builder.RegisterType<TestService>()
            .As<ITestService>();

        builder.RegisterType<TestApiA>()
                .AsImplementedInterfaces()
                .Keyed<ITestApi>(TestApiEnum.TestA)
                .WithAttributeFiltering()
                .WithParameter("testEnum", TestApiEnum.TestA);

        builder.RegisterType<TestApiB>()
               .AsImplementedInterfaces()
               .Keyed<ITestApi>(TestApiEnum.TestB)
               .WithAttributeFiltering()
               .WithParameter("testEnum", TestApiEnum.TestB);

var builder = AutofacConfig.ConfigureContainer();
        using (var scope = builder.BeginLifetimeScope())
        {
            // Able to Resolve following two..
            var testApiA = scope.ResolveKeyed<ITestApi>(TestApiEnum.TestA);
            var testApiB = scope.ResolveKeyed<ITestApi>(TestApiEnum.TestB);

            // following test service resolves both parameters as **testApiB** and **testApiB**
            var testservice = scope.Resolve<ITestService>();
        }   


Solution

  • i have similar problems with KeyFilter (link)

    In your case it is about the following: in constructor KeyFilter don't work - it is an issue :-( it will be resolved only by interface, by last registered interface :-( (in your case TestB)

    Check it out.

    first case : add:

    builder.RegisterType<TestApiB>()                   
                   .As<ITestApi>()
                   .WithAttributeFiltering()
                   .WithParameter("testEnum", TestApiEnum.TestC);
    

    and comment out your registrations (It doesn't matter) --> you (always) get TestC

    Second case: swap initial registration --> last registration will be used.

    Third case: comment out lines ".AsImplementedInterfaces()": you will get exception until don't register code of first case.