ASP.NET Core 6依赖注入解析带params构造函数服务报错问题
问题根因
这是ASP.NET Core内置依赖注入(DI)容器的版本行为差异导致的:
- ASP.NET Core 2.1版本的内置DI对带
params关键字的构造函数参数做了特殊兼容:如果容器中没有注册对应数组类型的服务,会默认传入空数组完成对象实例化,因此对应代码在2.1版本可以正常运行。 - 从ASP.NET Core 3.0版本开始,内置DI移除了这项特殊兼容逻辑:容器会严格按照构造函数声明的参数类型,逐一从服务容器中解析对应实例,不再对
params修饰的数组参数做隐式传空数组的处理。
注意params只是C#的语法糖,编译后对应的参数本质就是普通的数组类型,你定义的AuthorizePermission构造函数参数实际类型是string[],但没有在DI容器中注册string[]类型的服务,容器解析时找不到对应实例,就会抛出你看到的报错。
修复方案
可以根据实际业务需求选任意一种方式修复:
- 注册服务时显式指定实例化工厂,手动传入构造参数
如果不需要传入初始权限值,直接传空数组即可:
如果需要传入固定的权限值,直接在构造时传入即可:builder.Services.AddScoped<AuthorizePermission>(sp => new AuthorizePermission());
如果权限值需要从其他服务或配置中读取,可以通过工厂方法传入的builder.Services.AddScoped<AuthorizePermission>(sp => new AuthorizePermission("User:View", "User:Edit"));IServiceProvider实例解析对应依赖获取值后传入。 - 给类新增无参构造函数
DI容器选择构造函数时,会优先选择所有参数都能从容器中解析的重载,新增无参构造后,容器就会走无参构造实例化,不会再尝试解析string[]类型:public class AuthorizePermission { object[] Arguments; public AuthorizePermission() { Arguments = Array.Empty<object>(); } public AuthorizePermission(params string[] permissions) { Arguments = new object[] { permissions }; } }
内容的提问来源于stack exchange,提问作者werner giam
相关产品推荐
相关产品推荐

