C# 验证服务描述符时出错:检测到循环依赖项
我有两门课,C# 验证服务描述符时出错:检测到循环依赖项,c#,asp.net-core,dependency-injection,C#,Asp.net Core,Dependency Injection,我有两门课,AccountService: public class AccountService : IAccountService { private readonly UserManager<CustomIdentityUser> _userManager; private readonly SignInManager<CustomIdentityUser> _signInManager; private readonly RoleManag
AccountService
:
public class AccountService : IAccountService
{
private readonly UserManager<CustomIdentityUser> _userManager;
private readonly SignInManager<CustomIdentityUser> _signInManager;
private readonly RoleManager<CustomIdentityRole> _roleManager;
private readonly IUserRepository _userRepository;
private readonly LinkGenerator _linkGenerator;
private readonly IHttpContextAccessor _accessor;
private readonly IMediaService _mediaService;
public AccountService(
UserManager<CustomIdentityUser> userManager,
SignInManager<CustomIdentityUser> signInManager,
LinkGenerator linkGenerator,
IHttpContextAccessor accessor,
IMediaService mediaService,
RoleManager<CustomIdentityRole> roleManager,
IUserRepository userRepository)
{
_userManager = userManager;
_signInManager = signInManager;
_linkGenerator = linkGenerator;
_accessor = accessor;
_mediaService = mediaService;
_roleManager = roleManager;
_userRepository = userRepository;
}
public class MediaService : IMediaService
{
private readonly IMediaRepository _mediaRepository;
private readonly IAccountService _accountService;
private readonly IHttpContextAccessor _accessor;
public MediaService(
IMediaRepository mediaRepository,
IAccountService accountService,
IHttpContextAccessor accessor)
{
_mediaRepository = mediaRepository;
_accountService = accountService;
_accessor = accessor;
}
}
public AccountService(... Func<IMediaService> mediaServiceFactory,...)
{
...
_mediaService = mediaServiceFactory(); (or in place where it is called)
...
}
我在IoC层中注入了这两个元素:
services.AddScoped<IMediaService, MediaService>();
services.AddScoped<IAccountService, AccountService>();
services.addScope();
services.addScope();
但我在运行时遇到一个错误:
验证服务描述符“ServiceType:Aroma\u Shop.Application.Interfaces.IMediaService生存期:作用域实现类型:Aroma\u Shop.Application.Services.MediaService”时出错:检测到类型为“Aroma\u Shop.Application.Interfaces.IMediaService”的服务的循环依赖项
Aroma_Shop.Application.Interfaces.IMediaService(Aroma_Shop.Application.Services.MediaService)->Aroma_Shop.Application.Interfaces.IAccountService(Aroma_Shop.Application.Services.AccountService)->Aroma_Shop.Application.Interfaces.IMediaService“}
我理解问题所在,如果您查看两个类AccountService
和MediaService
,您会注意到,在这两个类中,我都请求注入另一个类。在AccountService
中,我请求service注入MediaService
,在MediaService
中从服务请求注入AccountService
服务描述符不能注入这两个类,因为当它想要注入AccountService
时,它需要MediaService
从中生成一个对象,而当它想要注入MediaService
时,它需要AccountService
从中生成一个对象
如果可能的话,请帮我解决这个问题。非常感谢。或者如果它们相互依赖,您可以为这两个服务提供一个单一的实现,例如
AccountAndMediaService : IAccountService, IMediaService
您还可以注册工厂以解决依赖关系。有些容器为已注册的服务提供内置的
Func
“工厂”,但使用Microsoft的工厂,您可以执行以下简单操作:
services.AddScoped(c=>c.GetRequiredService);
并在AccountService
中解析Func
而不是IMediaService
:
public class AccountService : IAccountService
{
private readonly UserManager<CustomIdentityUser> _userManager;
private readonly SignInManager<CustomIdentityUser> _signInManager;
private readonly RoleManager<CustomIdentityRole> _roleManager;
private readonly IUserRepository _userRepository;
private readonly LinkGenerator _linkGenerator;
private readonly IHttpContextAccessor _accessor;
private readonly IMediaService _mediaService;
public AccountService(
UserManager<CustomIdentityUser> userManager,
SignInManager<CustomIdentityUser> signInManager,
LinkGenerator linkGenerator,
IHttpContextAccessor accessor,
IMediaService mediaService,
RoleManager<CustomIdentityRole> roleManager,
IUserRepository userRepository)
{
_userManager = userManager;
_signInManager = signInManager;
_linkGenerator = linkGenerator;
_accessor = accessor;
_mediaService = mediaService;
_roleManager = roleManager;
_userRepository = userRepository;
}
public class MediaService : IMediaService
{
private readonly IMediaRepository _mediaRepository;
private readonly IAccountService _accountService;
private readonly IHttpContextAccessor _accessor;
public MediaService(
IMediaRepository mediaRepository,
IAccountService accountService,
IHttpContextAccessor accessor)
{
_mediaRepository = mediaRepository;
_accountService = accountService;
_accessor = accessor;
}
}
public AccountService(... Func<IMediaService> mediaServiceFactory,...)
{
...
_mediaService = mediaServiceFactory(); (or in place where it is called)
...
}
公共帐户服务(…Func mediaServiceFactory,…)
{
...
_mediaService=mediaServiceFactory();(或在调用它的位置)
...
}
还要注意的是,如果您有一些递归调用路径,您只是将其推迟到运行时,因此在无限递归的情况下,最终会出现StackOverflow异常,因此可能值得努力将重用功能的某些部分移动到另一个类,以防止这种循环依赖关系。出于好奇,您为什么需要这样做双向依赖?似乎有点奇怪。这暗示了总体架构中的一个问题。可能很少有需要双向依赖的情况,但如果可能的话,我会努力消除它。如果您确实需要双向依赖,您可以实现一个工厂,并将其作为依赖项而不是服务本身。您不能将其资本化e英语中的每一个单词……不,这并不奇怪,如果你看一下我的代码,你就会明白为什么我需要双向依赖——斯诺格鲁默对不起,我把最后一个单词都大写,只是为了清理——当然,我最好把类划分开来,然后进行分权,但这不是我问题的答案,而你只是抹掉了问题,我想,如果这些问题没有得到正确的回答,这就是问题的答案。@StevenNo,它们不是那么相互依赖,我在AccountService中使用电子邮件注入MediaService,在我注入AccountService的MediaService中注入AccountService将评论与用户关联问题的根源非常类似于单一责任违规(SRP)(帐户服务太大)。将其与媒体服务合并可能会解决循环依赖性,但只会夸大SRP问题。跨多个责任领域的事务应该由高级业务服务驱动。因此,IAccountService可以依赖于IMediaService,但如果您需要使用IMediaService并更新Acc的方法Count,属于IAccountService的。