升级到.NET Core 3.1后无法实例化单例PhysicalFileProvider
问题根因
你之前写的services.AddSingleton<IFileProvider, PhysicalFileProvider>()注册方式本身存在逻辑问题:PhysicalFileProvider的构造函数要求必须传入一个字符串类型的根目录路径,DI容器中没有对应参数的注册,自然无法完成实例化,所以抛出构造失败的运行时错误。
正确修改方案
- 先在Startup类的构造函数中注入
IHostEnvironment,存为类的私有只读字段,示例代码如下:
public class Startup { private readonly IHostEnvironment _env; public Startup(IConfiguration configuration, IHostEnvironment env) { Configuration = configuration; _env = env; } public IConfiguration Configuration { get; } // 其余原有代码保持不变 }
- 找到原有注册
services.AddSingleton<IFileProvider, PhysicalFileProvider>();这行,直接替换为以下代码即可:
services.AddSingleton<IFileProvider>(_env.ContentRootFileProvider);
如果你的原有业务是访问wwwroot下的静态资源,也可以替换为_env.WebRootFileProvider。如果需要指定自定义的特殊路径,就手动构造PhysicalFileProvider传入目标路径即可,示例如下:
// 示例:指定应用根目录下的Uploads文件夹作为文件提供程序根目录 var customPath = Path.Combine(_env.ContentRootPath, "Uploads"); services.AddSingleton<IFileProvider>(new PhysicalFileProvider(customPath));
修改后的影响说明
- 完全适配.NET Core 3.1的服务注册规则,不会再抛出服务构造失败的运行时错误
- 默认使用的
ContentRootFileProvider指向应用的根目录,和.NET Core 2.1时期默认的物理文件提供程序行为完全一致,不会影响原有API的文件读取、静态资源访问等功能 - 自定义路径的方案可以完全匹配你之前2.1版本的特殊业务需求,不会产生功能差异
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

