看似循环的依赖关系导致温莎城堡出现问题

发布于 2024-12-08 19:57:24 字数 1254 浏览 0 评论 0原文

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

  container.Register(
                AllTypes.FromAssemblyContaining<UserService>()
                .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. 

如何解决此问题?

I have a IUserService (and other services) that I am registering in bulk in my ServiceInstaller.cs:

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

I then I have IAuthenticationService which I register as in my generic WindsorInstaller.cs file:

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

Now things were working just fine until I added a public property for IAuthenticationService in my UserService.

It seems there is a circular dependacy or some timing issue of when things get registered, as I am getting the error:

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. 

How can I solve this issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱格式化 2024-12-15 19:57:24

您需要:

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

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

有关如何重构以删除循环依赖关系的详细说明,请参阅 Miško Hevery 撰写的博客文章:

You need to either:

  1. Get rid of your circular dependencies (this is the preferred option), or
  2. Work around them, by using property injection, rather than constructor injection.

Using property injection (as illustrated in Steven's answer) allows you to create instances of your classes without providing all the dependencies at the time of creation. The downside is that it is not as obvious to users of the class what they need to do to instantiate and fully configure the instance.

For a nice explanation of how to refactor to remove a ciruclar dependency see this blog post by Miško Hevery:

木格 2024-12-15 19:57:24

属性注入将解决您的问题,因为它打破了依赖循环。只需查看 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;

可以通过属性注入来打破循环依赖,并且可以将任何依赖注入框架配置为允许属性注入。

Property injection will solve your problem, because it breaks the dependency cycle. Just look at Krzysztof's example and try to instantiate a UserService; You can't. Now take a look at the following example:

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

public class AuthenticationService 
{
    AuthenticationService() { }

    public UserService UserService { get; set; }
}

In this example, the UserService dependency of the AuthenticationService is 'promoted' from a constructor argument to a property. Now you can create a user service like this:

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

Breaking the circular dependency can be done with property injection and any dependency injection framework can be configured to allow property injection.

独孤求败 2024-12-15 19:57:24

据我了解,这是您的场景:

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

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

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

here's your scenario as I understand it:

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

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

How would you create instances of both classes, creating at most single instance of each class?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文