0

我的控制器类有一个依赖项,例如:

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

但这必须在我所有的控制器中重复。我更喜欢进行属性注入,所以我可以像这样清理它:

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 {
}

为了让它发挥作用,我遵循了 docs

我改变了我的Startup.ConfigureServices()

services.AddControllers().AddControllersAsServices();

我在以下位置注册了控制器Startup.ConfigureContainer(ContainerBuilder builder)

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

这样可行。

但是文档说我可以注入一个特定的属性:

如果你有一个特定的属性和值要连接,你可以使用 WithProperty() 修饰符:builder.RegisterType<A>().WithProperty("PropertyName", propertyValue);

所以我必须更改我的代码:

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

如何propertyValue从容器中动态解析。并且,容器会在控制器类中注入任何其他属性,还是只注入那个?

4

1 回答 1

4

您尝试做的事情并不适合这种情况。正如您已经遇到的那样,如果在设置时知道具体值而不是动态分辨率。

我建议将其保留在容器将解决依赖关系并设置属性之前的工作方式。

//...

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

考虑到您的情况,您想要采取的方法确实是不必要的。

于 2021-07-08T14:06:24.657 回答