2

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

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

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

我如何忽略这些文件夹?

谢谢

WindsorControllerFactory 的异常

由于无法发布图像,我必须对其进行描述 - 它基本上只是说

'找不到内容控制器'

全球.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));

            }

        }
4

2 回答 2

1

我按照Steve Sanderson 的模式创建 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

于 2009-10-21T02:44:40.480 回答
1

只需使用MVCContrib

它包括集成 Windsor 和 ASP.NET MVC 的所有内容,包括控制器工厂注册控制器的扩展

于 2009-10-21T03:27:11.403 回答