Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在ASP.NET Core中注册单例工厂解析作用域对象?_C#_Asp.net Core_Dependency Injection_.net Core - Fatal编程技术网

C# 如何在ASP.NET Core中注册单例工厂解析作用域对象?

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 {

当我为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";
    }
}
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想要的是相反的结果。