core控制器属性注入的用处_如何使用Autofac和ASP.NET Core在控制器上启用属性注入?...

There doesn't really seem to be an easy way to make sure the controllers have property injection.

A way around it would be to register all controllers individually, which seems to defeat the purpose a bit. The [FromServices] attribute is removed and they specifically mention it should be up to the individual IoC containers to make sure this happens.

Am I missing something glaringly obvious? Looked for all available extension methods but didn't find anything, same for issues and the discussion forum.

解决方案

Yeah, setting up property injection for controllers with autofac is a bit tricky ;) but here is how it works.

With ASP.NET Core (2.1) you first need to register your controllers as services in your Startup.cs:

services.AddMvc().AddControllersAsServices();

otherwise property injection won't work as quoted from the 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.

You then need to register your services with the autofac container builder via populate and afterwards you can register your controllers with the autofac container.

Here is a shortened code excerpt from the autofac docs:

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);

}

It is important that you append .PropertiesAutowired() to allow property injection!

Now another thing to mention which may not be obvious is that autofac's PropertiesAutowired does not automatically consider every property of your service to be worty for property injection.

Checkout the DefaultPropertySelector from the github source code and you will see it will skip non-public ones:

if (!propertyInfo.CanWrite || propertyInfo.SetMethod?.IsPublic != true)

{

return false;

}

So you may need to create a custom PropertySelector that extends the DefaultPropertySelector in order to register the properties as being injectable based on your own logic. So you could do something like this:

var propSelector = new MyPropertySelector();

builder.RegisterType().PropertiesAutowired(propSelector);

In order to make sure that you do not always have to remember each single controller class, you can also register all your controllers in bulk:

builder.Populate(services);

var propSelector = new MyPropertySelector();

builder

.RegisterAssemblyTypes(typeof(Controller).Assembly)

.AssignableTo()

.InstancePerLifetimeScope()

.PropertiesAutowired(propSelector);

Hope this helps :)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值