2

ASP.NET MVC アプリケーションを作成し、Castle Windsor を IOC として使用しようとしています。

ただし、コントローラーが解決しようとしているときに、メソッドの「コントローラー名」パラメーターに「コンテンツ」と「スクリプト」を取得していますCreateController(RequestContext requestContext, string controllerName)。言うまでもなく、これらはコントローラーではありません。それらは Web サイトのフォルダーのようです

これらをコントローラーとして登録しようとするのはなぜですか?

これらのフォルダーを無視するにはどうすればよいですか??

ありがとう

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));

            }

        }
4

2 に答える 2

1

私はSteveSandersonパターンに従って、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);
}

技術的には、これは私が使用しているコードとは異なります。実際、Castle Windsor全体を、ComponentFactoryと呼ばれるクラスの静的インスタンスに抽象化しました。これにより、いくつかの強いタイプの追加の中で、アプリケーションを通じて真のシングルトンパターンを持つことができます。

ブログでComponentFactory()をまもなくリリースする予定なので、これについて言及します。しかし、私にメールを送ってください。最新バージョンをお送りします。メールアドレス:me -at- eduncan911.com

于 2009-10-21T02:44:40.480 に答える
1

MVCContribを使用してください。

これには、コントローラー ファクトリやコントローラーを登録するための拡張機能など、Windsor と ASP.NET MVC を統合するためのすべてが含まれています。

于 2009-10-21T03:27:11.403 に答える