我如何获得目前的Castle Windsor容器?

时间:2014-01-14 19:42:06

标签: c# castle-windsor

我是Castle 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
}

2 个答案:

答案 0 :(得分:17)

为此目的,温莎有接口。它被称为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;

答案 1 :(得分:8)

有很多方法可以解决这个问题,但我认为最常见的是创建一个单例辅助类来保存引用。请记住,您希望应用程序使用DI自动从容器中获取所有内容。也许只有来自应用程序的几个电话才能进入容器。看看温莎的控制器工厂。

像这样......

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

现在我已经知道更进一步了,你可以在get ...中添加一些实用程序。

    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吗?