Skip to content

RegisterTypes will attempt to register abstract types (undocumented breaking change in v6.5.0) #1388

@rosslovas

Description

@rosslovas

Describe the Bug

In Autofac v6.4.0, a scanning registration using RegisterTypes that includes types that cannot be constructed (e.g. interfaces, abstract classes) will work fine.

In Autofac v6.5.0 onwards, it will attempt to register those non-constructible types resulting in an Autofac.Core.Activators.Reflection.NoConstructorsFoundException upon building the container.

This is a breaking change that I couldn't find documented anywhere.

Steps to Reproduce

public class ReproTest
{
    interface IInterface { }

    class Class : IInterface
    {
    }

    [Fact]
    public void Repro()
    {
        var containerBuilder = new ContainerBuilder();

        containerBuilder
            .RegisterTypes(typeof(IInterface), typeof(Class))
            .AssignableTo<IInterface>();

        var exception = Record.Exception(() => containerBuilder.Build());

        Assert.Null(exception);
    }
}

Expected Behavior

No exception, test passes (v6.4.0 behaviour)

Exception with Stack Trace

v6.5.0 onwards throws:

Autofac.Core.Activators.Reflection.NoConstructorsFoundException: No accessible constructors were found for the type 'ReproTestProject.ReproTest+IInterface'.
   at Autofac.Core.Activators.Reflection.DefaultConstructorFinder.GetDefaultPublicConstructors(Type type)
   at Autofac.Core.Activators.Reflection.DefaultConstructorFinder.FindConstructors(Type targetType)
   at Autofac.Core.Activators.Reflection.ReflectionActivator.ConfigurePipeline(IComponentRegistryServices componentRegistryServices, IResolvePipelineBuilder pipelineBuilder)
   at Autofac.Core.Registration.ComponentRegistration.BuildResolvePipeline(IComponentRegistryServices registryServices, IResolvePipelineBuilder pipelineBuilder)
   at Autofac.Core.Registration.ComponentRegistration.BuildResolvePipeline(IComponentRegistryServices registryServices)
   at Autofac.Core.Registration.ComponentRegistryBuilder.Build()
   at Autofac.ContainerBuilder.Build(ContainerBuildOptions options)
   at ReproTestProject.ReproTest.<>c__DisplayClass2_0.<Repro>b__0()

Dependency Versions

Autofac: v6.5.0

Additional Info

A workaround is for the user to filter out abstract types from the types passed to RegisterTypes themselves.

In trying to figure out why I was getting this exception after upgrading to v6.5.0 from v6.4.0 I took a look at the diff between the two versions, and the removal of !t.IsAbstract in CanBeRegistered in this commit was something that stood out to me that might be the cause.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions