Круглые зависимости, вызывающие проблемы с замком Виндзор - PullRequest
2 голосов
/ 10 октября 2011

У меня есть 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)));

Теперь все работало нормально, пока я не добавил общедоступное свойство для IAuthenticationService в свой UserService.

Похоже, существует круговая зависимость или некоторая проблема времени, когда вещи регистрируются, так как я получаю сообщение об ошибке:

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. 

Как я могу решить эту проблему?

Ответы [ 3 ]

7 голосов
/ 11 октября 2011

Вам необходимо либо:

  1. избавиться от циклических зависимостей (это предпочтительный вариант), либо
  2. обойти их, используя внедрение свойств, а не конструкторвнедрение.

Использование внедрения свойств (как показано в ответ Стивена ) позволяет создавать экземпляры ваших классов без предоставления всех зависимостей на момент создания.Недостатком является то, что пользователям класса не так очевидно, что им нужно сделать для создания экземпляра и полной настройки экземпляра.

Подробное объяснение того, как выполнить рефакторинг для удаления зависимости от Circular, смотрите в этом сообщении в блоге.by Miško Hevery:

4 голосов
/ 11 октября 2011

Внедрение свойства решит вашу проблему, потому что оно нарушает цикл зависимости. Просто посмотрите на пример Кшиштофа и попытайтесь создать экземпляр UserService; Ты не можешь Теперь взгляните на следующий пример:

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

public class AuthenticationService 
{
    AuthenticationService() { }

    public UserService UserService { get; set; }
}

В этом примере UserService зависимость AuthenticationService "продвигается" из аргумента конструктора в свойство. Теперь вы можете создать пользовательский сервис, подобный этому:

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

Прерывание циклической зависимости может быть выполнено с помощью внедрения свойства, и любая структура внедрения зависимости может быть настроена так, чтобы разрешить внедрение свойства.

1 голос
/ 11 октября 2011

вот ваш сценарий, насколько я понимаю:

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

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

Как бы вы создали экземпляры обоих классов, создавая не более одного экземпляра каждого класса?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...