Как получить текущий контейнер Castle Windsor?

Я Замок Winsor Noob. У меня есть проект WebForm, который жаркий. Я пытаюсь разрешить зависимость для проверки регистрации пользователя. Как мне добраться до текущего WindsorContainer?

IWindsorContainer container = ???;
IRegistrationLogic registrationLogic = container.Resolve<IRegistrationLogic>();
_registrationLogic.Register();

Вот мой Bootstrapper:

public class WindsorConfigTask : ICastleBootstrapperTask
{

    public void Execute()
    {
        Container.AddFacility<WcfFacility>();
        Container.Register(
            Component.For<IProcessMessageRequest>()
                .ActAs(
                    new DefaultClientModel
                    {
                        Endpoint =
                            WcfEndpoint.ForContract<IProcessMessageRequest>().FromConfiguration("surveyClient2")
                    }
                ),
            Component.For<ILocalMembershipService>()
                .ActAs(
                    new DefaultClientModel
                    {
                        Endpoint =
                            WcfEndpoint.ForContract<ILocalMembershipService>().FromConfiguration(
                                "localMembershipClient")
                    })


            );

        Container.Register(Component.For<IRegistrationLogic>()
            .ImplementedBy<RegistrationLogic>()
            .LifeStyle.Is(LifeStyleType));
    }

    public IWindsorContainer Container { get; set; }


    #region ICastleBootstrapperTask Members


    public Castle.Core.LifestyleType LifeStyleType
    {
        get;
        set;
    }

    #endregion
}

Ответ 1

Есть много способов решить эту проблему, но я думаю, что наиболее распространенным является создание вспомогательного класса singleton для хранения ссылки. Имейте в виду, что вы хотите, чтобы приложение использовало DI, чтобы автоматически извлечь все из контейнера. Возможно, только несколько вызовов из приложения будут в контейнере. Посмотрите на фабрики контроллеров для Windsor.

Что-то вроде этого...

public static class ContainerManager
{
    public static IWindsorContainer Container = null;
}

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

    public static class ContainerManager
    {
        private static IWindsorContainer _container = null;
        public static IWindsorContainer Container
        {
             get {
                 if (_container == null) {
                      // run installers, set _container = new container
                 }
                 return _container;
             }

        }
    }

Я также понимаю, что вы можете спросить, как мне получить контейнер из зависимого от низа объекта... вы можете зарегистрировать контейнер сам. По умолчанию он зарегистрирует IKernel, но вы можете позже зарегистрировать IWindsorContainer для инъекций. Я бы очень не поощрял использование контейнера напрямую. Как в вашем коде выше... вы делаете Release, когда закончите???

Ответ 2

Для этого есть интерфейс в Виндзоре. Он называется IContainerAccessor. Лучшим местом для реализации является файл Global.asax:

public class WebApplication : HttpApplication, IContainerAccessor {
  static IWindsorContainer container;

  public IWindsorContainer Container {
    get { return container; }
  }

  protected void Application_Start() {
    var bootstrapper = new WindsorConfigTask();
    bootstrapper.Execute();
    container = bootstrapper.Container; 
  }

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

Использование в вашей веб-форме выглядит следующим образом:

var containerAccessor = Context.ApplicationInstance as IContainerAccessor;
var container = containerAccessor.Container;