【问题标题】:Circular reference in dependency injection依赖注入中的循环引用
【发布时间】:2021-10-14 06:09:52
【问题描述】:

我正在 Net 5 中创建一个 RESTful api,根据说明我必须创建使用它们的存储库和服务。逻辑必须在服务中。

我拥有的服务是:

子组服务 群组服务

我遇到的问题是我生成了一个循环引用,因为在 GroupsService 我需要一个 SubGroupsService 的方法,而 SubGroupsService 我需要一个 GroupsService 的方法。

将GroupsService服务注入SubGroupsService没有问题,但是将SubGroupsService注入GroupsService会产生循环引用。

请您告诉我如何解决此类问题,因为我对依赖注入没有太多经验。

子组服务

public class SubGroupService: ISubGroupService
{       
    private readonly ISubGroupRepository _SubGroupRepository;
    private readonly IGroupService _GroupService;        
    public SubGroupService(
        ISubGroupRepository SubGroupRepository,
        IGroupService GroupService
    {          
        _SubGroupRepository = SubGroupRepository;
        _GroupService = GroupService;        
    }

    public async Task InsertSubGroupService(Subgroup subgroup)
    {
        var group = await _GroupService.GetGroupService(subgroup.idgroup);
        
        if (group != null)
        {
            await _SubGroupRepository.InsertSubGroupRepository(subgroup);
        }
        else
        {
            throw new BusinessException("This group not exists");
        }
    }

    public async Task<Subgroups> GetSubGroupService(int idgroup)
    {
        return await _SubGroupRepository.GetSubGroupRepository(idgroup);
    }
}

团体服务

public class GroupService : IGroupService
{
    private readonly ISubGroupService _SubGroupService;
    private readonly IGroupRepository _GroupRepository;
    public GroupService(
        ISubGroupService SubGroupService,
        IGroupRepository GroupRepository)
    {
        _SubGroupService = SubGroupService;
        _GroupRepository = GroupRepository;
    }

    public async Task<bool> DeleteGroupService(int Idgroup)
    {
        var existsSubGroup = await _SubGroupRepository(Idgroup);
        if(existsSubGroup == null)
        {
            return await _GroupRepository.DeleteGroupRepository(Idgroup);

        }
    }

    public async Task<Groups> GetGroupService(int Idgroup)
    {
        return await _GroupRepository.GetGroupRepository(Idgroup);
    }
}

接口:

public interface IGroupService
{
    Task<Groups> GetGroupsService(int Idgroup);
    Task<bool> DeleteGroupService(int Idgroup);
}

public interface ISubGroupService
{
    Task<Subgroups> GetSubGroupService(int idsubgrupo);
    Task InsertSubgroupService(Subgroup subgroup);
}

【问题讨论】:

  • 如果GroupService 同时实现了IGroupServiceISubGroupService 会怎样?还是那不可能?
  • 以及为什么在SubGroupService 中需要_SubGroupRepository 等等...
  • _SubGroupService 在您的示例中未使用。如果服务方法只是调用存储库方法,为什么不直接调用存储库呢?或者将该服务的实现移至扩展方法。
  • 如果这只是一个服务和一个接口怎么办?不确定我完全理解你想要什么,但如果这是一个树结构,每个组都可以有子组,每个组都是一个子组。您可以添加一个方法来获取根组。
  • 你不应该处于这种情况,如果你有这样的循环依赖,你的服务很可能做错了事情,你的担忧是混乱的。这又是一个陷阱年轻玩家会陷入构思不良和被错误吹捧的存储库hokey pokey

标签: c# dependency-injection .net-5


【解决方案1】:

在这种情况下,您不能使用构造函数注入。你可以切换到属性注入:

public class SubGroupService: ISubGroupService
{       
    private readonly ISubGroupRepository _SubGroupRepository;
    public IGroupService GroupService { get; set; }
    public SubGroupService(
        ISubGroupRepository SubGroupRepository)
    {          
        _SubGroupRepository = SubGroupRepository;
    }

    // methods of the class
}

public class GroupService : IGroupService
{
    public ISubGroupService SubGroupService {get; set;}
    private readonly IGroupRepository _GroupRepository;
    public GroupService(
        IGroupRepository GroupRepository)
    {
        _GroupRepository = GroupRepository;
    }
    
    // methods of the class
}

您必须像这样创建对象:

IGroupRepository groupRepository = new GroupRepository();
IGroupService groupService = new GroupService(groupRepository);
ISubGroupService subGroupService = new SubGroupService(groupRepository);
groupService.SubGroupSerivce = subGroupService;
subGroupService.GroupService = groupService;

当然,现在创建对象要复杂得多。您可以将创建放入 facotry 方法以避免错误:

public (IGroupService,ISubGroupService) CreateGroupAndSubGroupService()
{
   // code from above
}

还建议添加空检查,因为有人可能会在未正确初始化服务的情况下创建对象。

【讨论】:

  • 尽管这回答了问题,但我认为 Allan 在走这条路之前应该重新考虑他们的设计。
  • @M.Dennhardt 问题本身,我想是我不想实现 UnitOfWork 模式时造成的。您如何建议重做这部分服务以避免这些错误?谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-14
  • 1970-01-01
  • 2010-11-29
  • 2018-03-03
  • 1970-01-01
  • 2017-03-24
相关资源
最近更新 更多