C# 看似循环的依赖关系导致Castle Windsor出现问题

C# 看似循环的依赖关系导致Castle Windsor出现问题,c#,dependency-injection,castle-windsor,C#,Dependency Injection,Castle Windsor,我有一个IUserService(和其他服务),我正在我的ServiceInstaller.cs中批量注册: container.Register( AllTypes.FromAssemblyContaining<UserService>() .Where(type => type.Name.EndsWith("Service")) .WithService.DefaultInt

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

  container.Register(
                AllTypes.FromAssemblyContaining<UserService>()
                .Where(type => type.Name.EndsWith("Service"))
                .WithService.DefaultInterface()
                .Configure(c => c.LifeStyle.Singleton)
                );
现在一切正常,直到我在UserService中为
iaauthenticationservice
添加了一个公共属性

这似乎是一个循环依赖性或一些时间问题,当事情得到登记,因为我得到的错误:

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. 

我如何解决这个问题?

根据我的理解,这是您的情况:

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

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

如何创建这两个类的实例,每个类最多创建一个实例?

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

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

public class AuthenticationService 
{
    AuthenticationService() { }

    public UserService UserService { get; set; }
}
在本例中,
AuthenticationService
UserService
依赖项从构造函数参数“升级”为属性。现在,您可以创建如下用户服务:

var a = new AuthenticationService();
var s = new UserService(a);
a.UserService = s;
打破循环依赖可以通过属性注入来完成,任何依赖注入框架都可以配置为允许属性注入。

您需要:

  • 摆脱循环依赖关系(这是首选选项),或者
  • 通过使用属性注入而不是构造函数注入来解决这些问题
  • 使用属性注入(如中所示)可以创建类的实例,而无需在创建时提供所有依赖项。缺点是,对于类的用户来说,实例化和完全配置实例所需的操作并不明显

    有关如何重构以删除ciruclar依赖项的详细说明,请参阅Miško Hevery的以下博客:


    循环依赖可以通过使用属性注入来解决。所以,如果是构造函数注入,它将不起作用,但使用属性它会起作用吗?为什么?要构造
    UserService
    必须调用其构造函数。要做到这一点,您必须有一个
    AuthenticationService
    ,它需要在构造函数中传递一个
    UserService
    ,它需要一个
    AuthenticationService
    ,它需要……“如何通过不具有循环依赖关系来解决此问题?”->这是直接的解决方案。然而,值得指出的是,循环依赖通常是设计缺陷的一种迹象。一个更好的解决方案是执行根本原因分析,以完全消除循环依赖关系。此外,我想指出,从API设计的角度来看,构造函数注入和属性注入并不等效,因为它们暗示了对类的不变量的不同保证。我完全同意Mark的观点。属性注入对我很有效。然而,我需要完全摆脱构造函数,并将这些类完全移动到属性注入。
    var a = new AuthenticationService();
    var s = new UserService(a);
    a.UserService = s;