似乎没有一种简单的方法可以确保控制器具有属性注入.
解决这个问题的方法是单独注册所有控制器,这似乎有点失败了. [FromServices]属性是removed,他们特别提到它应该取决于各个IoC容器以确保发生这种情况.
我错过了一些明显的东西吗?查找所有可用的扩展方法,但没有找到任何内容,相同的问题和讨论论坛.
最佳答案 是的,为具有autofac的控制器设置属性注入有点棘手;)但这是它的工作原理.
使用ASP.NET Core(2.1),您首先需要在Startup.cs中将控制器注册为服务:
services.AddMvc().AddControllersAsServices();
否则财产注入将无法按照autofac docs引用:
By default, ASP.NET 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容器注册您的控制器.
以下是autofac docs的缩短代码摘录:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddControllersAsServices();
var builder = new ContainerBuilder();
builder.Populate(services);
builder.RegisterType<MyController>().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<MyController>().PropertiesAutowired(propSelector);
为了确保您不必总是记住每个控制器类,您还可以批量注册所有控制器:
builder.Populate(services);
var propSelector = new MyPropertySelector();
builder
.RegisterAssemblyTypes(typeof(Controller).Assembly)
.AssignableTo<Controller>()
.InstancePerLifetimeScope()
.PropertiesAutowired(propSelector);
希望这可以帮助 :)