是的,为具有autofac的控制器设置属性注入有点棘手;)但这是它的工作原理.
使用 Core(2.1),您首先需要在Startup.cs中将控制器注册为服务:
services.AddMvc().AddControllersAsServices();
否则财产注入将无法按照autofac docs引用:
By default, Core will resolve the controller parameters from the container but doesn’t actually resolve the controller from the container. This usually isn’t an issue but it does mean: […] Special wiring that you may have done during registration of the controller (like setting up property injection) won’t work.
然后,您需要通过populate向autofac容器构建器注册您的服务,然后您可以使用autofac容器注册您的控制器.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddControllersAsServices();
var builder = new ContainerBuilder();
builder.Populate(services);
builder.RegisterType().PropertiesAutowired();
this.ApplicationContainer = builder.Build();
return new AutofacServiceProvider(this.ApplicationContainer);
}
附加.PropertiesAutowired()以允许属性注入非常重要!
现在另一件可能不明显的事情是,autofac的PropertiesAutowired并不会自动将服务的每个属性都视为属性注入的worty.
检查github source code中的DefaultPropertySelector,您将看到它将跳过非公开的:
if (!propertyInfo.CanWrite || propertyInfo.SetMethod?.IsPublic != true)
{
return false;
}
因此,您可能需要创建一个自定义PropertySelector,它扩展DefaultPropertySelector,以便根据您自己的逻辑将属性注册为可注入的.所以你可以这样做:
var propSelector = new MyPropertySelector();
builder.RegisterType().PropertiesAutowired(propSelector);
为了确保您不必总是记住每个控制器类,您还可以批量注册所有控制器:
builder.Populate(services);
var propSelector = new MyPropertySelector();
builder
.RegisterAssemblyTypes(typeof(Controller).Assembly)
.AssignableTo()
.InstancePerLifetimeScope()
.PropertiesAutowired(propSelector);
希望这可以帮助 :)
core控制器属性注入的用处-core – 如何使用Autofac和 Core在控制器上启用属性注入?...