在 .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引擎。
首先,您需要注册 settings
和 resourceSetting
对象
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));
}
...
}
我正在尝试将接口和设置传递到 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引擎。
首先,您需要注册 settings
和 resourceSetting
对象
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));
}
...
}