看似循环的依赖导致Castle Windsor的问题

我有一个IUserService(和其他服务),我在ServiceInstaller.cs中批量注册:

container.Register( AllTypes.FromAssemblyContaining() .Where(type => type.Name.EndsWith("Service")) .WithService.DefaultInterface() .Configure(c => c.LifeStyle.Singleton) ); 

然后,我有IAuthenticationService,我在我的通用WindsorInstaller.cs文件中注册:

  container.Register(Component.For(typeof (IAuthenticationService)) .ImplementedBy(typeof(AuthenticationService))); 

现在一切正常,直到我在UserService中为IAuthenticationService添加了一个公共属性。

当事情被注册时,似乎存在循环依赖或某些时间问题,因为我收到错误:

 Can't create component 'ABCD.Services.UserService' as it has dependencies to be satisfied. ABCD.Services.UserService is waiting for the following dependencies: Services: - ABCD.Services.Interfaces.IAuthenticationService which was registered but is also waiting for dependencies. ABCD.Services.AuthenticationService is waiting for the following dependencies: Services: - ABCD.Services.Interfaces.IUserService which was registered but is also waiting for dependencies. 

我该如何解决这个问题?

你需要:

  1. 摆脱你的循环依赖(这是首选选项),或
  2. 通过使用属性注入而不是构造函数注入来解决它们。

使用属性注入(如Steven的答案中所示 )允许您创建类的实例,而无需在创建时提供所有依赖项。 缺点是,对于类的用户来说,实例化和完全配置实例需要做什么并不明显。

有关如何重构以消除ciruclar依赖关系的一个很好的解释,请参阅MiškoHevery的这篇博客文章:

  • 构造函数和dependency injection中的循环依赖

属性注入将解决您的问题,因为它打破了依赖循环。 只需看看Krzysztof的示例并尝试实例化UserService ; 你不能。 现在看一下下面的例子:

 public class UserService { UserService(AuthenticationService a) { } } public class AuthenticationService { AuthenticationService() { } public UserService UserService { get; set; } } 

在此示例中, AuthenticationServiceUserService依赖项从构造函数参数“提升”到属性。 现在您可以创建这样的用户服务:

 var a = new AuthenticationService(); var s = new UserService(a); a.UserService = s; 

可以使用属性注入来完成循环依赖性,并且可以配置任何依赖性注入框架以允许属性注入。

这是我理解的情景:

 public class UserService { UserService(AuthenticationService a){} } public class AuthenticationService { AuthenticationService (UserService a){} } 

您将如何创建两个类的实例,最多创建每个类的单个实例?