首先,让我们看一下代码:
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();
}
如果我把所有东西都改成构造函数,它就像一个魔咒一样工作,但是,这里使用注入属性的主要思想是为了避免构造函数地狱。
在上面的代码片段中,有一些注释,其中我提到了什么是有效的,什么不是,当没有使用泛型时,属性注入可以正常工作。
所以,我在问你们,我在这里做错了什么,我的代码缺少了什么才能正常工作?
非常感谢!
发布于 2020-10-14 15:07:54
你在这里遇到的问题主要是你在哪里指定了
PropertiesAutowired
,而不是你要解决的问题。
我已经更新了你的
RegisterServices
方法,增加了一些注释。
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.