2015-03-06 1 views
2

Я в отладке внутри конструктора, инициализированного Виндзором. Мне нужно найти ссылку на контейнер Windsor, чтобы использовать следующую строку кода.Как отлаживать, когда виндзор разрешает контейнеры?

container.Resolve<IPerson>(new { id = 5 }); 

Но у меня нет контейнера с переменными. Решение имеет 200 проектов, и мне нужно найти, где начинается Виндзор.

Какая современная техника отлаживает эту проблему? Есть ли способ найти исходный код, где происходит операция .Resolve?


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

  • Глядя на стек вызовов
  • Включение другой обработки из Visual Studio
  • Игра с Exception параметр «Просто мой код»
  • запись в quickwatch Transaction.Current (который является видимым во всем видимом классе)

ответ

0
  1. Получить к корне композиции -> Класс/фабрика/все, в чем начинается разрешение.

  2. Найти зарегистрированные фабрики в классе основной установки. Вероятно, какой-то класс, который реализует IWindsorInstaller. Если ваш проект такой большой, у вас, вероятно, будет несколько классов установщика для разных модулей приложения. В Core Installer вы, вероятно, найдете фабрики, которые Castle использует для создания и предоставления частей всего графа объектов.

  3. Осмотрите его тщательно с помощью ручки и бумаги, расчесывающих весь графический объект, чтобы свести к минимуму работу догадки во время отладки и не попасть в «отладочную съемку», которая является исчерпывающей, и в конце вы ничего не узнали о системе , Найдите, где параметры для конструктора приходят.

  4. Поместите свои точки перерыва в методах XXXфакторов/фабрик/XXXtypeFactoryComponentSelectors и выполните полный цикл отладки с несколькими запросами.

Хорошего сеанс отладки :)

1

Windsor не решает контейнеры, так как вам нужно контейнер разрешить службу к компоненту. Обычно контейнер представляет собой корневой состав, что означает, что он руководит созданием всех компонентов, которые могут вам понадобиться. Использование контейнера в коде не является хорошей идеей, поскольку он связывает определенный код с общей настройкой вашего приложения.

Вы должны использовать тот факт, что контейнер может разрешить необходимые вам компоненты; вот способы сделать это:

  • Добавить параметр IPerson в конструкторе, и пусть это решить IPerson для вас. Если разрешение статично (т. Е. Всегда один и тот же идентификатор), вы можете сообщить Windsor о разрешении службы на specific instance.
  • Если вы не можете разрешить IPerson при построении конструктора, разрешите IPersonFactory в вашем объекте. Этот factory займет целое число и вернет IPerson. Таким образом, вы все еще отделены от контейнера, но можете загрузить нужные данные.
  • Если вам действительно нужно использовать контейнер (хотя вы можете обойтись без него), вы можете зарегистрировать службу IWindsorContainer во время конфигурации контейнера и добавить свой конструктор в свой конструктор IWindsorContainer; контейнер будет доступен вашему объекту.

Хотя это просто, я действительно не рекомендую последний подход; чтобы ваш код знал о контейнере, на самом деле не рекомендуется

1

Я в отладке внутри конструктора, инициализированного Виндзором. ... Но у I нет контейнера переменной.

Это одна из основных причин использования контейнеров IoC - чтобы ваш код был чистым и отвечал за создание объекта.

Решение имеет 200 проектов, и мне нужно найти, где начинается Виндзор.

Windsor запускается там, где вызывается его конструктор new WindsorContainer() (см. Bootstrapping Windsor).

container = new WindsorContainer() 
    .Install(FromAssembly.This()); 

Для веб-приложения MVC вы найдете эти строки кода в Global.asax.cs.

Есть ли способ найти исходный код, где происходит операция .Resolve ?

например. для веб-приложения MVC это происходит в пользовательских контроллера завода, который инициализируется в Global.asax.cs

var controllerFactory = new WindsorControllerFactory(container.Kernel); 
ControllerBuilder.Current.SetControllerFactory(controllerFactory); 

Существует example of custom controller factory implementation:

public class WindsorControllerFactory : IControllerFactory 
{ 
    private readonly WindsorContainer _container; 

    public WindsorControllerFactory(WindsorContainer container) 
    { 
     _container = container; 
    } 

    public IController CreateController(RequestContext requestContext, string controllerName) 
    { 
     return (IController)_container.Resolve(controllerName); 
    } 

    public void ReleaseController(IController controller) 
    { 
     _container.Release(controller); 
    } 
} 

Так _container.Resolve(controllerName) это место, где вызывается метод Resolve. Решение (создание, создание) контейнера контроллера пытается разрешить все его зависимости, используя информацию о зарегистрированных типах.