C# 如何在ASP.NET Core中注册单例工厂解析作用域对象?
当我为IPersonProvider注册工厂时,如下所示:C# 如何在ASP.NET Core中注册单例工厂解析作用域对象?,c#,asp.net-core,dependency-injection,.net-core,C#,Asp.net Core,Dependency Injection,.net Core,当我为IPersonProvider注册工厂时,如下所示: services.AddScoped<IPersonProvider, PersonProvider>(); services.AddSingleton<Func<IPersonProvider>>(sp => () => sp.GetService<IPersonProvider>()); public class HomeController : Controller {
services.AddScoped<IPersonProvider, PersonProvider>();
services.AddSingleton<Func<IPersonProvider>>(sp => () => sp.GetService<IPersonProvider>());
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";
}
}
services.addScope();
services.AddSingleton(sp=>()=>sp.GetService());
我得到一个错误:
InvalidOperationException:无法从根提供程序解析作用域服务“DependencyApp.Provider.IPersonProvider”
我知道我无法解析具有作用域依赖项的单例对象,但据我所知,我的工厂没有任何作用域依赖项——事实上,它没有任何依赖项。当我要求这样做时,它只是创建对象:
services.AddScoped<IPersonProvider, PersonProvider>();
services.AddSingleton<Func<IPersonProvider>>(sp => () => sp.GetService<IPersonProvider>());
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";
}
}
公共类HomeController:控制器
{
私有只读功能工厂;
公共家庭控制器(Func工厂)
{
_工厂=工厂;
}
[路线(“/”)]
公共字符串计算()
{
var personProvider=_factory();
//.
//.
//.
返回“测试”;
}
}
为什么我会犯这个错误呢?如何解决这个问题?我相信,将工厂注册为单例,只要整个应用程序能够生存,创建作用域对象就不会有任何问题-最终,这些创建的对象并不是单例的真正依赖项。出现此问题的原因是使用了
IServiceProvider
实例。将服务注册为singleton时,根IServiceProvider
将传递给工厂方法
因此,当你有:
services.AddSingleton<Func<IPersonProvider>>(sp => () => sp.GetService<IPersonProvider>());
但是,当您的工厂方法是瞬时生存期时,传入的sp
不再使用根服务提供程序,而是使用一个派生的提供程序,其中实例化作用域服务的限制不适用
要重申这个问题,您使用的
sp
无法创建作用域服务,因此返回的服务不是Func
,而是提供者是根提供者这一事实。我已经完成了以下工作:
services.AddSingleton<ITokenManager, TokenManger>();
services.AddScoped<ITokenProvider, TokenProvider>();
public class TokenProvider : ITokenProvider
{
private readonly ITokenManager _tokenManager;
public TokenProvider(ITokenManager tokenManager)
{
_tokenManager = tokenManager;
}
}
services.AddSingleton();
services.addScope();
公共类令牌提供者:ITokenProvider
{
私有只读ITokenManager\u令牌管理器;
公共令牌提供者(ITokenManager令牌管理器)
{
_tokenManager=tokenManager;
}
}
如果将您的Func
设置为临时服务,这仍然是一个问题吗?问题可能是,由于它是一个单例,sp
实例始终是根实例,如果您将服务定义为瞬态,则情况可能并非如此。当我保留Func singleton但使IPersonProvider为瞬态时,它也能工作。但我想知道为什么我不能保持Func单例和提供程序的作用域?Func只是在创建对象,没什么,所以我认为我应该在每个应用程序中创建一次。我认为OP想要的是相反的结果。