基于这个问题的答案:Cyclic dependency with ninject和这个问题:Ninject: give the parent instance to a child being resolved这两个问题都说你可以使用双向属性注入来解决循环依赖关系,只要你将范围改为不是默认的瞬态范围。所以我尝试这样做,我有一个UserService
和一个GroupService
相互要求(请不要说改变类或使用第三类等等!)。我有一个使用ninject的通用EntityServiceFactory
,如下所示:
public static class EntityServiceFactory
{
public static TServiceClass GetService<TServiceClass>()
where TServiceClass : class
{
IKernel kernel = new StandardKernel();
return kernel.Get<TServiceClass>();
}
}
我的服务:
public class GroupService : EntityService<GroupRepository, Group, DbContext>
{
public UserService _userService { private get; set; }
public GroupService(GroupRepository repository, UserService userService) : base(repository)
{
userService._groupService = this;
}
public class UserService : EntityService<UserRepository, User, DbContext>
{
public GroupService _groupService { private get; set; }
public UserService(UserRepository repository, GroupService groupService)
: base(repository)
{
groupService._userService = this;
}
然后根据这些问题的答案中的说明,将以下内容添加到我的EntityServiceFactory
:
kernel.Bind<GroupService>().ToSelf().InCallScope();
kernel.Bind<UserService>().ToSelf().InCallScope();
但我仍然得到错误:
在两个构造函数之间检测到周期性依赖性 服务。
我是否正确地进行双向属性注射?我该如何解决这个问题?
答案 0 :(得分:2)
Welp,事实证明我不理解我所链接的问题中的答案。我根本没做任何类似属性注入的事情,我最终做的是:
只要有循环依赖,我就会从构造函数中删除一个循环诱导服务,并将其替换为:
private UserService _userService;
private UserService UserService
{
get { return _userService ?? (_userService = EntityServiceFactory.GetService<UserService>()); }
}
这实际上最终非常接近属性注入(http://ninject.codeplex.com/wikipage?title=Injection%20Patterns)。它不像构造函数注入那样最优,但仍然不是一个糟糕的解决方案。我也可以这样做(实际房产注入):
private UserService _userService;
[Inject]
private UserService UserService
{
get { return _userService; }
set { _userService = value; }
}
我只是选择了我的方式,因为它不需要我的服务有ninject特定的代码,以防我改变了它的用法,但调用EntityServiceFactory.GetService
基本上与[Inject]
做同样的事情属性。