我的控制器类只有一个依赖项,例如:
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 {
}
为了让它发挥作用,我遵循了文档。
我更改了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
。AND,容器会在控制器类中注入任何其他属性吗?还是只注入那个属性?
您尝试做的并不是针对那个场景的。正如您已经遇到的那样,如果在设置时已知特定值,而不是关于动态分辨率。
我建议让它保持以前的工作方式,容器将解析依赖项并设置属性。
//...
public void ConfigureContainer(ContainerBuilder builder) {
var types =
typeof(Startup).Assembly
.GetExportedTypes()
.Where(type => typeof(MyControllerBase).IsAssignableFrom(type))
.ToArray();
builder.RegisterTypes(types).PropertiesAutowired();
}
考虑到您的情况,您想要采取的方法确实没有必要。