Может кто-нибудь объяснить, как Castle Windsor работает в моем приложении? - PullRequest
3 голосов
/ 13 января 2011

Я начал использовать Castle Windsor, и мое приложение каким-то образом работает, но я не совсем понимаю, как оно работает. Не направляйте меня к документации, иначе меня бы здесь не было.

В моем Global.asax.cs у меня есть это:

private static IWindsorContainer container;

protected void Application_Start()
{
  AreaRegistration.RegisterAllAreas();
  RegisterRoutes(RouteTable.Routes);
  BootstrapContainer();
} 

protected void Application_End()
{
  container.Dispose();
}

private static void BootstrapContainer()
{
 container = new WindsorContainer()
                .Install(FromAssembly.This());

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

Теперь это регистрация новой фабрики контроллеров, которую я понимаю. Установка WindsorContainer из текущей сборки, я думаю, регистрирует все установщики, например, у меня есть установщик хранилища. Я предполагаю, что контейнер, созданный в Global.asax, передается установщикам.

public class RepositoriesInstaller : IWindsorInstaller
{
     public void Install(IWindsorContainer container, IConfigurationStore store)
    {

        container.Register(AllTypes.FromThisAssembly()
                 .Where(type => type.Name.EndsWith("Repository"))
                 .WithService.DefaultInterface()
                 .Configure(c => c.LifeStyle.PerWebRequest));
    }
}

В моем контроллере я создал конструктор и передал аргумент IRepository. Я не понимаю, как контроллер принимает этот аргумент.

Во-вторых, в качестве теста я создал 2 класса репозитория, которые реализуют IRepository. Помещая точку останова в конструктор контроллера, она передается в один из этих классов. Как мне отобразить, какой класс, который реализует IRepository, должен быть передан в конструктор?

У меня также есть Fluent NHibernate. На следующем этапе я бы хотел, чтобы IRepository зависел от ISession. Как мне это сделать?

Спасибо за вашу помощь

1 Ответ

6 голосов
/ 13 января 2011

Поскольку вы зарегистрировали фабрику контроллеров, которая использует Windsor, именно контейнер IoC Windsor отвечает за разрешение всех ваших экземпляров контроллера по мере необходимости.

То есть, когда вы получаете доступ к URL-адресу в вашем MVC-проекте, который указывает на действие «Индекс» в вашем «HomeController», ваш WindsorControllerFactory будет запрашивать инфраструктуру MVC экземпляр HomeController.

Если у этого контроллера есть конструктор, который принимает экземпляр IRepository , и вы зарегистрировали IRepository как службу с контейнером , тогда Windsor будет знать, как удовлетворить зависимость класса HomeController. Поэтому он может сначала преобразовать IRepository в некоторый конкретный класс, создать его экземпляр и передать его в качестве параметра конструктору HomeController перед возвратом экземпляра HomeController в инфраструктуру MVC.

Если вам нужны разные реализации IRepository для разных целей (например, UserRepository и ProductRepository), вы можете создать для них отдельные интерфейсы, каждый из которых расширяет IRepository, например ::

public interface IProfileRepository : IRepository {}

Затем вы можете использовать свободный интерфейс регистрации Windsor для регистрации всех конкретных классов, реализующих IRepository, и регистрации их в конкретной службе, которую они предоставляют, например, IProfileRepository.

Если вы сделаете это, Windsor автоматически разрешит все экземпляры, которые реализуют IRepository, без необходимости писать новый регистрационный код при добавлении новой реализации.

Что касается зависимости классов репозитория от ISession, вы можете сделать это несколькими способами. Я бы порекомендовал , а не , позволяя им напрямую зависеть от сеанса, а скорее позволить им зависеть от класса, через который они могут получить текущий сеанс (чтобы вы могли совместно использовать сеансы между репозиториями). В Интернете много информации о том, почему это хорошая практика, просто выполните поиск.

Теперь, что касается фактического осуществления этого, вы можете:

  • Зарегистрируйте экземпляр класса (по интерфейсу), который будет извлекать для вас сеанс с Windsor и позволит Windsor разрешить этот класс в качестве параметра для ваших конструкторов репозитория.

  • Зарегистрируйте ISession в Windsor и используйте заводской метод, чтобы получить его после разрешения.

...