问题描述
我的控制器类只有一个依赖项,例如:
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 {
}
为了让它发挥作用,我关注了 the 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
。并且,容器会在控制器类中注入任何其他属性,还是只会注入该属性?
解决方法
您尝试执行的操作不适合该场景。 正如您已经遇到的那样,如果在设置时已知特定值,则与动态分辨率无关。
我建议在容器将解析依赖项并设置属性之前保持它的工作方式。
//...
public void ConfigureContainer(ContainerBuilder builder) {
var types =
typeof(Startup).Assembly
.GetExportedTypes()
.Where(type => typeof(MyControllerBase).IsAssignableFrom(type))
.ToArray();
builder.RegisterTypes(types).PropertiesAutowired();
}
考虑到您的情况,您想要采用的方法确实没有必要。