C# 控制器中ASP.NET核心MVC FromService binding返回空集合

C# 控制器中ASP.NET核心MVC FromService binding返回空集合,c#,dependency-injection,asp.net-core,singleton,asp.net-core-mvc,C#,Dependency Injection,Asp.net Core,Singleton,Asp.net Core Mvc,我一直在尝试使用ASP.NET Core MVC,但由于依赖项注入在我的控制器操作中返回空集合而陷入困境,尽管在ConfigureService方法中将服务注册为Singleton。尝试了两种不同的注册方式,但其中只有一种真正有效。所述方法如下: public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); /***THI

我一直在尝试使用ASP.NET Core MVC,但由于依赖项注入在我的控制器操作中返回空集合而陷入困境,尽管在
ConfigureService
方法中将服务注册为Singleton。尝试了两种不同的注册方式,但其中只有一种真正有效。所述方法如下:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();
    /***THIS DOES NOT WORK***/
    services.AddSingleton<IRepository<Employee>, EmployeeRepository>();
    var empRepo = services.BuildServiceProvider().GetService<IRepository<Employee>>();
    empRepo.Create( "emp001" );

    /***THIS WORKS***/
    var employeeRepository = new EmployeeRepository();
    employeeRepository.Create( "emp001" );
    services.AddSingleton<EmployeeRepository>( employeeRepository );
}
public void配置服务(IServiceCollection服务)
{
//添加框架服务。
services.AddMvc();
/***这行不通***/
services.AddSingleton();
var empRepo=services.BuildServiceProvider().GetService();
empRepo.创建(“emp001”);
/***这很有效***/
var employeeRepository=新employeeRepository();
employeeRepository.Create(“emp001”);
服务。AddSingleton(员工住所);
}
以下是我的控制器操作:

[HttpGet( "{empID}" )]
public string GetEmployee( string empID, [FromServices] IRepository<Employee> employees **/*THIS IS ALWAYS EMPTY*/**)
{
    ....
}
[HttpGet(“{empID}”)]
公共字符串GetEmployee(字符串empID,[FromServices]i存储员工**/*此字符串始终为空*/**)
{
....
}

请给我指出正确的方向。两种
AddSingleton
方法之间有什么区别?我如何使用DI对控制器操作的第一种方法访问服务?TIA.

由于在控制器操作中,您需要一个
IRepository
的实例,因此只要注册的服务属于该类型,您就可以使用这两种方法中的任何一种(在第二种方法中,您将其注册为
EmployeeRepository
):

  • 更新HomeController中的索引操作,以使用
    [FromServices]
    接收实例,如中所示:

    public IActionResult Index([FromServices]IRepository<Employee> emp)
    
    然后在每次调用索引操作时添加新员工:

    public IActionResult Index([FromServices]IRepository<Employee> repo)
    {
        repo.Create($"client-{ Guid.NewGuid() }");
        return View();
    }
    
    public IActionResult索引([FromServices]i回购)
    {
    repo.Create($“client-{Guid.NewGuid()}”);
    返回视图();
    }
    
    您将看到,无论您使用哪种方法注册singleton,您的控制器都将获得相同的实例,并且员工将添加到相同的列表中


    还请记住另一个@Tseng的评论,他在评论中提到,单身可能不是存储库的最佳选择。通常,它将依赖于每个请求实例化的某个DbContext。(除非您创建某种形式的DbContext提供程序,并且您的repo依赖于它,但这不是主题)

    您的存储库是如何实现的?我想你在里面注入了DbContext?那么您就不能使用
    newemployeerepository()
    来实例化它,也不能使用singleton
    DbContext
    是按作用域解析的,因此,所有使用它的服务都必须这样做

    也不要在
    ConfigureServices
    中调用
    services.BuildServiceProvider()
    ,因为在调用
    Configure
    之前,ASP.NET Webstack将以任何方式执行此操作,并创建一个新的提供程序,与您以前构建的提供程序无关


    第三,永远不要通过应用程序作用域解析作用域服务(通过调用
    app.ApplicationServices.GetService()
    ,这可能会导致服务的生命周期出现问题。如果已解析作用域服务(即数据种子设定)在应用程序启动期间,创建一个新的作用域,从中解析,然后在完成后进行处理。

    我不得不回到我唯一的工作选项,这是@Daniel J.G.建议使用的;
    AddSingleton()
    在初始化存储库后(以及他提供的一些有用提示)。不过,我希望在初始化后使用另一个选项。

    感谢您突出显示两者之间的差异。当我使用第一个选项时,我不会收到null,而是收到一个初始化但为空的存储库,尽管在使用第一个选项初始化后执行了以下代码。
    var emprep=seReVist.BuffdService Posivor().GETService();EnPrimo.Cube(“EMPON1”);< /COD>添加了一些澄清说明。
    解决它的方法。我调用
    服务.BuildServiceProvider()
    的唯一原因是使用一些虚拟数据初始化某些服务,以便在调用控制器操作时显示它。整个项目中还没有涉及
    DbContext
    public IActionResult Index([FromServices]IRepository<Employee> emp)
    
    public class EmployeeRepository : IRepository<Employee>
    {
        private List<string> employees = new List<string>();
        public void Create(string employeeId)
        {
            this.employees.Add(employeeId);
        }
    }
    
    public IActionResult Index([FromServices]IRepository<Employee> repo)
    {
        repo.Create($"client-{ Guid.NewGuid() }");
        return View();
    }