简体   繁体   English

使用 Autofac 和 ASP.NET Core 控制器进行属性注入

[英]Property injection with Autofac and ASP.NET Core controller

My controller classes have a single dependency, eg:我的控制器类只有一个依赖项,例如:

public class UserController : ControllerBase {
  public UserController(IMediator mediator) => _mediator = mediator;
  private readonly IMediator _mediator;
}

But that must be duplicated in all my controllers.但这必须在我所有的控制器中复制。 I'd prefer to do property injection, so I could clean it up like this:我更喜欢进行属性注入,所以我可以像这样清理它:

public abstract class MyControllerBase : ControllerBase {
  public IMediator Mediator { get; init; }  // use init so container resolves this and cannot be changed later
}

public class UserController : MyControllerBase {
}

To get that working, I followed the docs .为了让它工作,我遵循了 docs

I changed my Startup.ConfigureServices() :我改变了我的Startup.ConfigureServices()

services.AddControllers().AddControllersAsServices();

And I registered controllers in Startup.ConfigureContainer(ContainerBuilder builder) :我在Startup.ConfigureContainer(ContainerBuilder builder)注册了控制器:

builder
  .RegisterAssemblyTypes(typeof(Startup).Assembly)
  .AssignableTo<MyControllerBase>()
  .InstancePerLifetimeScope()
  .PropertiesAutowired();

That works.这样可行。

However the docs say that I can inject a specific property:但是文档说我可以注入一个特定的属性:

If you have one specific property and value to wire up, you can use the WithProperty() modifier: builder.RegisterType<A>().WithProperty("PropertyName", propertyValue);如果您有一个特定的属性和值要连接,您可以使用 WithProperty() 修饰符: builder.RegisterType<A>().WithProperty("PropertyName", propertyValue);

So I have to change my code:所以我必须改变我的代码:

var types =
  typeof(Startup).Assembly
  .GetExportedTypes()
  .Where(type => typeof(MyControllerBase).IsAssignableFrom(type))
  .ToArray();

foreach (var type in types)
  builder.RegisterType(type).WithProperty(nameof(MyControllerBase.Mediator), propertyValue);

How can I dynamically resolve propertyValue from the container.如何从容器动态解析propertyValue AND, will the container inject any other properties in controller classes, or would it inject that one only?并且,容器会在控制器类中注入任何其他属性,还是只会注入那个属性?

What you are trying to do wasn't meant for that scenario.您尝试做的事情并不适用于这种情况。 As you have already encountered, it for if the specific value is known at the time of setup not about dynamic resolution.正如您已经遇到的那样,如果在设置时已知特定值而不是动态分辨率。

I suggest leaving it the way it was working before where the container will resolve the dependency and set the property.我建议在容器将解析依赖项并设置属性之前保持它的工作方式。

//...

public void ConfigureContainer(ContainerBuilder builder) { 
    var types =
        typeof(Startup).Assembly
        .GetExportedTypes()
        .Where(type => typeof(MyControllerBase).IsAssignableFrom(type))
        .ToArray();
    
    
    builder.RegisterTypes(types).PropertiesAutowired();
}

The approach you want to take is really unnecessary given your scenario.鉴于您的情况,您想要采用的方法确实是不必要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM