Search code examples
c#.net-coreautofac

Inherited class property injection with autofac


I hope to register with autofac property injection,But can't work ClassA property = null.Not injected successfully,how to change my code

public interface IRepository
{
}

public class Repository : IRepository
{
    public Repository()
    {

    }

}

this my base class

public class RepositoryBase : Repository
{
    public ClassA ClassA { get; set; }
    public RepositoryBase()
    {
            
    }

    public void Print()
    {
        ClassA.Exec();
    }
}

//Does property injection need to inject ClassA?

public class ClassA
    {
        public ClassA()
        {

        }

        public void Exec()
        {
            Console.WriteLine("Test");
        }
    }

call method

public interface ITestRepository
{
    void ExecPrint();
}

public class TestRepository : RepositoryBase, ITestRepository
{
    public TestRepository()
    {

    }

    public void ExecPrint()
    {
        Print();
    }
}

this my autofac register code

public class ContainerModule : Module
        {
            protected override void Load(ContainerBuilder builder)
            {
                var assembly = Assembly.GetExecutingAssembly();
                builder.RegisterAssemblyTypes(assembly)
                    .Where(t => t.Name.EndsWith("Repository"))
                    .AsImplementedInterfaces()
                    .InstancePerLifetimeScope()
                    ;
    
                builder.RegisterType<ClassA>().InstancePerLifetimeScope();
        builder.RegisterType<RepositoryBase>().InstancePerLifetimeScope().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
            }
        }

call Screenshots

RepositoryBase ClassA property = nulll


Solution

  • You are specifying PropertiesAutowired for the base class, but not for the main types.

    So changing your registration to :

    var assembly = Assembly.GetExecutingAssembly();
            builder.RegisterAssemblyTypes(assembly)
                .Where(t => t.Name.EndsWith("Repository"))
                .AsImplementedInterfaces()
                .InstancePerLifetimeScope()
                .PropertiesAutowired()
                ;
    
    builder.RegisterType<ClassA>().InstancePerLifetimeScope();
    

    Will make sure that the final implementations do receive the property.

    Also since I guess you would resolve by :

    var container = builder.Build();
    var test = container.Resolve<ITestRepository>();
    test.ExecPrint();
    

    You do not need to register RepositoryBase, autofac does not require the full class hierarchy to be registered, only the final type you use.