在 .Net Core 中实例化 startup.cs 中的 class 对象

Instantiate a class object in startup.cs in .Net Core

我正在尝试将接口和设置传递到 class,同时在 .Net 核心项目的 startup.cs 中创建 class 的实例。我正在使用下面的代码来这样做。我在 Student class 的构造函数中编写了一些代码,但是在启动应用程序 时,构造函数 中的 Code/Logic 无法正常工作。没有错误,但调试指针没有命中 Student class.

的构造函数
services.AddSingleton(c => new Student(settings, resourceSetting, c.GetService<IPersonService>()));

如果我使用下面的代码,那么 Student 构造函数中的代码工作正常。

 Student studentHandler = new Student(settings, resourceSetting,);
 services.AddSingleton<Student>(studentHandler);

但是我需要在构造函数中传递服务接口来在启动项目时做一些工作。谁能帮我解决我在这里缺少的东西?

the debug pointer is not hitting the constructor of Student class

那是因为您在第一个片段中将类型注册为实现工厂,使用 AddSingleton<TService> (this IServiceCollection services, Func<IServiceProvider,TService> implementationFactory) 使用此方法,实现工厂委托(以及随后的 Student 构造函数)不会被调用直到依赖被解决.

在第二个代码片段中,您直接在服务注册时实例化类型,并使用 AddSingleton<TService> (this IServiceCollection services, TService implementationInstance) 将该实例添加到服务集合中。


这是一个示例,其中包含解释每种方法中每个步骤的日志:

class Program
{
    static void Main(string[] args)

    {
        RegisterImplementationFactory();
        RegisterImplementation();
    }

    static void RegisterImplementationFactory()
    {
        Console.WriteLine("RegisterImplementationFactory ------------");

        var services = new ServiceCollection();

        Console.WriteLine("Registering Student...");
        services.AddSingleton(c => new Student());
        Console.WriteLine("Student registered.");

        Console.WriteLine("Building ServiceProvider...");
        var serviceProvider = services.BuildServiceProvider();
        Console.WriteLine("ServiceProvider built.");

        Console.WriteLine("Resolving Student...");
        Student student = serviceProvider.GetService<Student>();
        Console.WriteLine("Student resolved.");

        Console.WriteLine("RegisterImplementationFactory ------------");
        Console.WriteLine();
    }

    static void RegisterImplementation()
    {
        Console.WriteLine("RegisterImplementation ------------");

        var services = new ServiceCollection();

        Console.WriteLine("Registering Student...");
        Student studentToRegister = new Student();
        services.AddSingleton(studentToRegister);
        Console.WriteLine("Student registered.");

        Console.WriteLine("Building ServiceProvider...");
        var serviceProvider = services.BuildServiceProvider();
        Console.WriteLine("ServiceProvider built.");

        Console.WriteLine("Resolving Student...");
        Student student = serviceProvider.GetService<Student>();
        Console.WriteLine("Student resolved.");

        Console.WriteLine("RegisterImplementation ------------");
        Console.WriteLine();
    }
}

class Student
{
    public Student()
    {
        Console.WriteLine("!!! Instantiating Student...");
    }
}

这个输出是:

RegisterImplementationFactory ------------
Registering Student...
Student registered.
Building ServiceProvider...
ServiceProvider built.
Resolving Student...
!!! Instantiating Student...
Student resolved.
RegisterImplementationFactory ------------

RegisterImplementation ------------
Registering Student...
!!! Instantiating Student...
Student registered.
Building ServiceProvider...
ServiceProvider built.
Resolving Student...
Student resolved.
RegisterImplementation ------------

有了这个你可以清楚地看到,当使用工厂委托注册时,Student 构造函数不会被调用,直到类型被解析(在这种情况下使用 GetService<Student>())。

看来你使用了依赖注入,所以我建议根据你的构造函数进一步利用DI引擎。

首先,您需要注册 settingsresourceSetting 对象

services.AddSingleton<Student>(settings);
services.AddSingleton<Student>(resourceSetting);

然后也注册您的 Student class

services.AddSingleton<Student>();

现在,一旦您通过 .BuildServiceProvider();ServiceCollection 构建到 ServiceProvider 中(如果您正在开发控制台应用程序),您可以调用:

var myStudent = myServiceProvider.GetRequiredService<Student>();

如果您以 asp.net 之类的方式执行此操作,那么您只需将 Student class 注入控制器或其他此类服务以供使用

class MyController : ControllerBase
{

    private Student Student { get; }

    public MyController(Student student)
    {
       Student = student ?? throw new ArgumentNullException(nameof(student));
    }
 
    ...
}