using System;
using Autofac;
namespace PropertyInjectionAutofacPoC
public interface IInterfaceA { }
public interface IInterfaceB
IInterfaceA ClassA { get; set; }
public class ClassA : IInterfaceA { }
public class ClassB : IInterfaceB
public IInterfaceA ClassA { get; set; } // this is injected properly //
public class Z { }
public interface IInterfaceC<T> { }
public interface IInterfaceD<T>
IInterfaceA ClassA { get; set; }
IInterfaceC<T> ClassC { get; set; }
public interface IInterfaceCZ : IInterfaceC<Z> { }
public abstract class ClassD<T> : IInterfaceD<T>
public IInterfaceA ClassA { get; set; } // this is not injected, it's always null //
public IInterfaceC<T> ClassC { get; set; } // this is not injected, it's always null //
public abstract class ClassC<T> : IInterfaceC<T> { }
public sealed class ClassCZ : ClassC<Z>, IInterfaceCZ { }
public interface IRepositoryZ : IInterfaceD<Z> { }
public sealed class RepositoryZ : ClassD<Z>, IRepositoryZ { }
internal class Program
private static IContainer _container;
private static void Main()
RegisterServices();
// it works //
var a = _container.Resolve<IInterfaceB>();
// it doesn't work //
var b = _container.Resolve<IRepositoryZ>(); // ClassC property is null
catch (Exception e)
Console.WriteLine(e);
finally
DisposeServices();
private static void RegisterServices()
var builder = new ContainerBuilder();
builder.RegisterType<ClassA>().As<IInterfaceA>();
builder.RegisterType<ClassB>().As<IInterfaceB>().PropertiesAutowired(); // works like a charm //
builder.RegisterGeneric(typeof(ClassC<>)).As(typeof(IInterfaceC<>)).PropertiesAutowired();
builder.RegisterGeneric(typeof(ClassD<>)).As(typeof(IInterfaceD<>)).PropertiesAutowired(); // it doesn't work //
builder.RegisterType<ClassCZ>().As<IInterfaceCZ>();
builder.RegisterType<RepositoryZ>().As<IRepositoryZ>();
_container = builder.Build();
private static void DisposeServices()
if (_container != null &&
_container is IDisposable disposable)
disposable.Dispose();
}
private static void RegisterServices()
var builder = new ContainerBuilder();
builder.RegisterType<ClassA>().As<IInterfaceA>();
builder.RegisterType<ClassB>().As<IInterfaceB>().PropertiesAutowired();
// These registrations aren't really valid. You would never be able to
// resolve IInterfaceC<> or IInterfaceD<>, because they are abstract classes, so cannot be constructed.
// You'll always get a NoConstructorsFoundException.
builder.RegisterGeneric(typeof(ClassC<>)).As(typeof(IInterfaceC<>)).PropertiesAutowired();
builder.RegisterGeneric(typeof(ClassD<>)).As(typeof(IInterfaceD<>)).PropertiesAutowired();
builder.RegisterType<ClassCZ>().As<IInterfaceCZ>();
// When I resolve IRepositoryZ, this is the registration that gets provided. So this is where you need PropertiesAutowired.
// Just because RepositoryZ derives from ClassD<Z> does not mean it inherits any of its component registration information,
// which I think is what you may have been expecting.