【问题标题】:Why is Castle Windsor trying to resolve my 'Content' and 'Scripts' folder as a controller?为什么 Castle Windsor 试图将我的“内容”和“脚本”文件夹解析为控制器?
【发布时间】:2009-10-21 02:20:44
【问题描述】:

我创建了一个 ASP.NET MVC 应用程序并尝试使用 Castle Windsor 作为我的 IOC

但是,当控制器尝试解析时,我在 CreateController(RequestContext requestContext, string controllerName) 方法中的“controllerName”参数中获取了“内容”和“脚本”。不用说这些不是控制器。它们似乎是网站的文件夹

为什么要尝试将这些注册为控制器?

如何忽略这些文件夹??

谢谢

WindsorControllerFactory 的异常

由于无法发布图片我不得不描述它 - 它基本上只是说

'找不到内容控制器'

Global.asax.cs

public static IIocContainer Ioc;

            protected void Application_Start()
            {
                InitialiseIocContainer();
                RegisterViewEngine(ViewEngines.Engines);
                RegisterRoutes(RouteTable.Routes);
                StartProfiling();
            }


private void InitialiseIocContainer()
        {
            IWindsorContainer _container = new WindsorContainer();

            var controllerTypes = typeof (GidgetController).Assembly.GetTypes();
            foreach (var controllerType in controllerTypes.Where((t=>typeof(IController).IsAssignableFrom(t))))
            {
                _container.AddComponentLifeStyle(controllerType.Name.ToLower(), controllerType, LifestyleType.Transient);   
            }


            _container.AddComponent("a",typeof(IGidgetService), typeof(GidgetService));
            _container.AddComponent("b",typeof(IGidgetRepository), typeof(GidgetRepository));
            _container.AddComponent("c",typeof(IGidgetValidator), typeof(GidgetValidator));


            ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(_container));

        }

windsorControllerFactory.cs

public IController CreateController(RequestContext requestContext, string controllerName)
        {
            try
            {
                controllerName = controllerName.ToLower() + "controller";
                var controller = _container.Resolve<IController>(controllerName);
                return controller;
            }
            catch (ComponentNotFoundException)
            {
                throw new HttpException(404, string.Format("The {0} controller was not found", controllerName));

            }

        }

【问题讨论】:

    标签: c# dependency-injection castle-windsor ioc-container


    【解决方案1】:

    只需使用MVCContrib

    它包括集成 Windsor 和 ASP.NET MVC 的所有内容,包括 controller factoryextensions to register controllers

    【讨论】:

      【解决方案2】:

      我按照Steve Sanderson's 模式创建了一个WindsorControllerFactory,效果很好。当没有控制器的名称(即有人键入“/garbageblahblah”)时,我已经修改了他以实际返回正确的 404,因为他的模式没有选择它。因此,我使用 Reflector 来获取默认控制器工厂中内置的位以处理错误的 url。

      他的模式使用反射来查找 Mvc 项目中的所有控制器,并在应用启动时将它们全部注册。您不想使用 CreateController,而是使用 GetControllerInstance(),因为它仅在要调用控制器时由底层 Mvc 框架调用。 /Content 按照惯例会被忽略,因此不会被调用。

      我的 CastleWindsorControllerFactory:

      /// <summary>
      /// Represents a special controller factory.
      /// </summary>
      public class CastleWindsorControllerFactory : DefaultControllerFactory
      {
          WindsorContainer _container;
      
          public CastleWindsorControllerFactory()
          {
              // register all controllers from the calling assembly.
              // (e.g. the mvc site calling this factory)
              //
              _container =
                  new WindsorContainer(
                      new XmlInterpreter(
                          new ConfigResource("castle")
                      )
                  );
      
              // change this to Assembly.GetAssembly() if used directly from
              // your MVC website.  The code below is for when this class
              // exists in a seperate assembly.
              //
              var controllers =
                  from t in Assembly.GetCallingAssembly().GetTypes()
                  where typeof(IController).IsAssignableFrom(t)
                  select t;
      
              foreach (Type t in controllers)
                  _container.AddComponentLifeStyle(
                      t.FullName, t, LifestyleType.Transient); 
          }
      
          protected override IController GetControllerInstance(Type controllerType)
          {
              if (controllerType == null)
              {
                  throw new HttpException(
                      0x194
                      , string.Format(
                          CultureInfo.CurrentUICulture
                          , "Controller Not Found"
                          , new object[] {
                              this.RequestContext.HttpContext.Request.Path }));
              }
              if (false == typeof(IController).IsAssignableFrom(controllerType))
              {
                  throw new ArgumentException(
                      string.Format(
                          CultureInfo.CurrentUICulture
                          , "Type does not sub-class the controller base"
                          , new object[] { controllerType }), "controllerType");
              }
      
              return 
                  (IController) _container.Resolve(controllerType);
          }
      }
      

      在我的 Globals.asax.cs 中,这就是你所需要的(你上面的内容太夸张了!我已经在上面的 CastleWindsorControllerFactor 中循环并注册了它们)。

      protected void Application_Start()
      {
          RegisterRoutes(RouteTable.Routes);
      
          // custom controller factory that uses Windsor
          ControllerBuilder.Current.SetControllerFactory(
              new CastleWindsorControllerFactory());
      
          // Uncomment to debug routes
          //RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);
      }
      

      从技术上讲,这并不是我使用的代码。实际上,我已经将整个温莎城堡抽象为一个名为 ComponentFactory 的类中的静态实例。这使我可以通过我的应用程序拥有真正的单例模式,以及几个强类型添加。

      我之所以提到这一点,是因为我计划很快在我的博客上发布 ComponentFactory()。但是,给我发电子邮件,我会将最新版本发送给您。电子邮件是:me -at- eduncan911.com

      【讨论】:

      • 看起来你的 ComponentFactory 实际上是一个服务定位器,对于 IoC 容器来说不是一个好主意。在 controllerfactory 中创建容器和注册控制器违反了 SRP,这不是它的责任。
      • @Mauricio Scheffer:对违反 SRP 投了 -1 票?真的吗?他没有对 DDD 或 SRP 表示任何担忧(他说工作的 MVCContrib 与我发布的内容相同)。那么,在 ASP.NET MVC 站点中自动注册 100 个 IController 的解决方案是什么? “检索”控制器将是工厂模式的责任,这不违反 SRP。这使用 IoC 容器来更轻松地处理它。
      • 抱歉,我不认为这是个好建议。我猜我们必须同意不同意……
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-03
      • 2016-05-18
      • 2010-11-28
      • 1970-01-01
      • 2016-02-26
      • 1970-01-01
      • 2017-02-13
      相关资源
      最近更新 更多