2015-10-13 5 views
1

Я использую единство в приложении Winforms, введя зависимость в конструктор формы (я знаю, что это не лучшая практика), но он работает, но я получаю исключение stackoverflowexception, когда я пытаюсь загрузите форму mdi.StackoverflowException при использовании Unity IOC

есть ли способ отслеживать, какое единство пытается решить и как-то узнать, что происходит?

У меня есть рабочий пример, который я знаю, работает с использованием этого «дизайна».

Я знаю, что это не идеальный дизайн, и я планирую введения Presenter вниз линии, но сейчас это должно работать, и я не знаю, почему это не

EDIT: Я знаю, что есть услуги что ссылки друг на друга, например,

public class Service1(IService2, IService3, IService4):IService1 

public class Service2(IService1, IService5):IService2 

приведет ли это к исключению?

EDIT2: yes Я только что создал быстрое приложение с этой круглой ссылкой, как указано в моем первом редактировании, и я получил исключение StackOverflowException - очевидно, не разрешено.

+0

"в конструктор формы". Это на самом деле лучшая практика. Ctor инъекции прекрасно работает в форме выигрыша, и инъекция ctor - лучшая практика, когда дело доходит до инъекции зависимости. – Steven

ответ

3

Когда вы поймаете исключение в VS, войдите в него и следуйте InnerException. Unity должен печатать все зарегистрированные типы, и вы можете видеть, что отсутствует.

Также посмотрите на трассировку стека. Обычно StackOverflow появляется, когда у вас есть круговое dependecies как это:

class A { A(B b) { ... } } 
class B { B(A a) { ... } } 

A зависит от B и наоборот. Unity попытается ввести в ctor из A экземпляр B, но экземпляру B нужен экземпляр A, который также нуждается в B и так далее.

Этот пример является тривиальной, но в реальной работе округлость труднее определить, как там может быть более сложным, график зависимостей между различными библиотеками, как A ->B ->C ->D ->A (где «->» означает «зависит от»).

EDIT Да, перекрестные ссылки услуг может привести вас к StackOverflow исключением, если в данный момент вы решения IService1, IService1 сам еще не зарегистрирован;

Решение 1 Вы можете обойти эту проблему, если регистрация типы и разрешения происходит в два этапа (грубая идея):

  1. Регистрация регистрирующих как IService1 и его тип и IService2 и его тип. Этот шаг делает только регистрационный код и не обрабатывает никаких других вещей (пользовательский интерфейс, логика запуска, разрешение на единицу, http comms и т. Д.).

  2. Запускается фактическая логика приложения; теперь вы можете разрешить что угодно.

Раствор 2

Используйте пустой ctors и делает решимость внутри Service класса. Вы можете использовать RegisterType метод, чтобы указать, что пустой ctor должен называться:

container.RegisterType<IServiceProvider, ServiceContainer>(new InjectionConstructor()); 

Вот более подробная информация о circular references with dependency injection using Unity.

Решение 3

Использование Lazy<IService> разрешения. Используя это, фактическое разрешение будет происходить по требованию, более конкретное, когда впервые в первый раз вызывается свойство Lazy.Value.

+0

см. Мое редактирование .. это то, что вы имеете в виду в этом случае, я буду иметь циркулярные ссылки – kurasa

+1

Отредактировано с дополнительными комментариями и некоторыми возможными решениями. – tomab

+0

URL-адрес дополнительной информации в решении2 пуст – kurasa

Смежные вопросы