c# - 如何在 ASP.NET Core 中注册解析作用域对象的单例工厂?
问题描述
当我像这样为 IPersonProvider 注册工厂时:
services.AddScoped<IPersonProvider, PersonProvider>();
services.AddSingleton<Func<IPersonProvider>>(sp => () => sp.GetService<IPersonProvider>());
我收到错误:
InvalidOperationException:无法从根提供商解析范围服务“DependencyApp.Provider.IPersonProvider”。
我知道我无法解析具有 Scoped 依赖项的 Singleton 对象,但据我所知,我的工厂没有任何 Scoped 依赖项 - 实际上它没有任何依赖项。当我要求这样时,它只会创建对象:
public class HomeController : Controller
{
private readonly Func<IPersonProvider> _factory;
public HomeController(Func<IPersonProvider> factory)
{
_factory = factory;
}
[Route("/")]
public string Calculate()
{
var personProvider = _factory();
//.
//.
//.
return "test";
}
}
为什么我会收到此错误?如何解决问题?我相信将工厂注册为单例,只要整个应用程序在创建作用域对象时没有任何问题——最终这些创建的对象并不是单例的真正依赖项。
解决方案
您遇到此问题的原因是由于使用的实例IServiceProvider
。当您将服务注册为单例时,根IServiceProvider
将传递给工厂方法。
所以当你有:
services.AddSingleton<Func<IPersonProvider>>(sp => () => sp.GetService<IPersonProvider>());
这意味着sp
必须与单例生命周期兼容,它只是根服务提供者。
为了说明我的意思。
using (var scopedServiceProvider = sp.CreateScope())
{
scopedServiceProvider.GetService<IPersonProvider>(); // valid
sp.GetService<IPersonProvider>(); // not valid
}
但是,当您的工厂方法具有瞬态生命周期时,sp
传入的方法不再使用根服务提供者,而是使用派生的服务提供者,其中实例化范围服务的限制不适用。
重申这个问题,sp
您正在使用的 无法创建范围服务,因此返回的服务不是 a 的问题Func
,而是提供者是根的事实。
推荐阅读
- javascript - jQuery AJAX JSON 数据被展平
- node.js - 用 Sequelize 返回外键的表数据
- wordpress - 仅在需要时将多部分编码标志添加到 WordPress 元框
- java - Thymleaf 模板无法评估与模型相关的表达式
- asp.net-mvc - 多个共享布局 mvc
- ruby-on-rails - 无法通过 React Native 应用调用验证 Rails API 中的 CSRF 令牌
- android - 如何更新视图位置
- php - 我在 cPanel 上放了 cron 作业命令,但它不起作用
- python - 如何将 __init__ 参数传递给使用 qmlRegisterType 注册的类?
- tfs-2015 - 如何使用户能够在 Backlog 视图中添加功能