C# .NET核心异常:检测到类型为的服务的循环依赖项

C# .NET核心异常:检测到类型为的服务的循环依赖项,c#,asp.net-core,dependency-injection,inversion-of-control,ioc-container,C#,Asp.net Core,Dependency Injection,Inversion Of Control,Ioc Container,最近我问了一个关于软件架构的问题 在回答了这个问题之后,我重新组织和重构了我的应用程序。通过一种简单的方式,我的服务相互调用,StudentService需要ClassService(例如获得平均班级分数),ClassService需要StudentService(获得分配给班级的学生)。类别(简化)如下所示: public class StudentService : IStudentService { protected readonly IClassService ClassSe

最近我问了一个关于软件架构的问题

在回答了这个问题之后,我重新组织和重构了我的应用程序。通过一种简单的方式,我的服务相互调用,StudentService需要ClassService(例如获得平均班级分数),ClassService需要StudentService(获得分配给班级的学生)。类别(简化)如下所示:

public class StudentService : IStudentService
{
    protected readonly IClassService ClassService;
    public StudentService(IClassService classService)
    {
        ClassService = classService;
    }
}

public class ClassService : IClassService
{
    protected readonly IStudentService StudentService;
    public ClassService(IStudentService studentService)
    {
        StudentService = studentService;
    }
}
服务在.NETCore中的DI容器中注册

services.AddTransient<IStudentService, StudentService>();
services.AddTransient<IClassService, ClassService>();
services.AddTransient();
services.AddTransient();
在解决过程中

var studentService = app.ApplicationServices.GetService<IStudentService>();
var studentService=app.ApplicationServices.GetService();
我收到一个异常,检测到类型为的服务存在循环依赖关系

我理解这里的实现问题,但我不知道如何解决这里的架构问题

你能提供一些建议吗

编辑: 好的,我有更现实的案例,例如员工、服务和公司。 我们有一个带有抽象通用CRUD存储库的存储库层。 然后我们有派生类:EmployeesRepository服务sRepository和CompanysRepository。 EmployeesRepository实现方法:getTopEmployeesSofthemonth ServicesRepository实现方法:GetTopServicesForEmployees CompanyRepository实现方法:GetCompanyWithTopIncome

在上面的层上,(我们称之为业务层),我们有相同的结构: 抽象通用CRUD助手,例如检查用户权限并从CRUD存储库调用方法。 然后我们得到了EmployeesHelper、ServicesHerlper和CompanyHelper。 它们都检查用户权限并从适当的存储库调用方法(EmployeesRepository中的EmployeesHelper等)。 此外,在这一层上,我们有创建更“复杂”对象的方法——由许多实体组成的对象。 例如,CompanyHelper有一种方法可以显示销售服务最多的前五大公司。 数据将显示在一个屏幕上,因此它应该由一个API请求生成,并作为JSON返回。 ShowCompanyWithServices from CompanyHelper方法调用CompanyHelper方法和EmployeesHelper方法。 在第二方面,我们有EmployeesHelper,它实现了返回复杂对象的方法,其中包含当月的顶级员工, 他们的顶级服务和他们工作的公司,因此需要companies助手

如何解决这种循环依赖关系?有什么设计模式可以解决这个问题吗

您有两种方法:

  • 编写代码,这样就不需要从StudentService调用ClassService(或从ClassService调用StudentService)

  • 创建第三类:

    public class StudentService: IStudentService
    {
        private readonly IClassSharedSerive _classSharedService;
        ...
    }
    
    public class ClassService: IClassService
    {
        private readonly IClassSharedSerive _classSharedService;
        private readonly IStudentService _studentService;
        ...
    }
    
    public class ClassSharedService: IClassSharesService
    {
        ... without references to IClassService and IStudentService
    }
    

  • 但是,在大多数情况下,需要正确地编写StudentService和ClassService(方式1)

    我不完全确定我的处理方式是否非常干净,但它对我来说很好。当我遇到循环依赖性问题时,我将服务从依赖性注入中移除,并将服务作为参数传递给需要它的函数

    因此,当您调用该方法时,它如下所示:

    // Inside the Student service
    var result = _classService.GetClassStudents(classId, this)
    
    可能不适用于所有人,但在我的情况下,我有一个非常简单的设置,所以我没有深入挖掘


    希望这有帮助。

    所以,我不认为服务应该注入其他服务

    我认为每个服务都应该能够独立地提供它负责的数据。如果IStudentService的使用者需要来自两个来源的数据,则它也可以是IClassService的使用者