ASP.NET MVCについてもチマチマと、とりあえず基本のあたり(1)

先月にASP.NET MVC 1.0がリリースされているわけですが、国内では情報も少ないし、あまり流行ってないカンジですかね(・ω・)?
Web Formsをやっている人達から見ると、こういうやり方は面倒だと思われるかもしれないし、LL言語でやっている人達から見ると、.NETなんてないわ〜という事かもしれませんが(´д`;)


個人的には、これで.NETでもJava*1でもPHPでも同じやりかたで出来るというメリットはあったりします(・∀・)


Web Formsは、グリッドとフォームだらけのイントラアプリには、現状、最も生産性の高いフレームワークだと思いますけど。*2
でも、コンシューマなWebサイトの条件には合致しないところがあるというか、Web Formsを使うメリットが生かせなかったりするので、そういう用途にはむしろASP.NET MVCの方がありがたかったりすると思いまふ(´ω`)
まあ、コンシューマサイトだと、PHPJavaの方を使う可能性が高いですけど。*3


っで、個人的にも少し弄ってみるべということで、遊び始めました(・∀・)
でも、(国内には)あまり情報も無いので、ここ数日はソースを読んでいたりして。
一通りは目を通したので、そのアウトプットと言うことで、ちょっと本格的なアプリを作る上では必須になる拡張ポイントの基本のあたりについて。

Controller Factoryの拡張

コントローラ(IController-ControllerBase-Controller派生)の生成はIControllerFactory派生のファクトリクラスで行われるので、コントローラのインスタンス生成前後に拡張を入れたい場合は独自のファクトリクラスを作成してそれを使用します。
標準のファクトリはDefaultControllerFactoryですが、これを継承してファクトリクラスを作ってみます。


とりあえずこんなカンジで(・∀・)

public class MyControllerFactory : DefaultControllerFactory
{
    public override IController CreateController(RequestContext requestContext, string controllerName)
    {
        return base.CreateController( requestContext, controllerName );
    }

    protected override Type GetControllerType(string controllerName)
    {
        return base.GetControllerType( controllerName );
    }

    protected override IController GetControllerInstance(Type controllerType)
    {
        IController controller = base.GetControllerInstance( controllerType );

        // 例えば依存性の注入みたいな
        IContainer container = ContainerFactory.GetContainer();
        container.Inject( controller );

        return controller;
    }
}

名前からコントローラの型を取得するGetControllerType()と、型からインスタンスを生成するGetControllerInstance()はDefaultControllerFactoryでvirtualに宣言されています。
ここではGetControllerInstance()を上書きして、インスタンスの生成自体はDefaultControllerFactoryの実装をそのまま使用し、IControllerのインスタンス生成後に小細工を行う〜ような例になっています。


IControllerのインスタンスもコンテナから直接取得したいような場合には、IControllerFactoryを直に実装して、以下のようなファクトリを作れば良いと思います(・∀・)

public class MyControllerFactory : IControllerFactory
{
    public IController CreateController(RequestContext context, string controllerName)
    {
        if( string.IsNullOrEmpty( controllerName ) )
        {
            throw new ArgumentNullException( "controllerName" );
        }

        IContainer container = ContainerFactory.GetContainer();
        return container.GetObject<IController>( controllerName );
    }

    public void ReleaseController(IController controller)
    {
        var disposable = controller as IDisposable;
        if( disposable != null )
        {
            disposable.Dispose();
        }
    }
}

っで、以下のようにして独自のファクトリが使用されるように設定します。

// Global.asax.cs
public class MvcApplication : System.Web.HttpApplication
{
...
    protected void Application_Start()
    {
        RegisterRoutes( RouteTable.Routes );

        // カスタムControllerFactoryの設定
        ControllerBuilder.Current.SetControllerFactory( new MyControllerFactory() );
    }
}

っというわけで、コントローラ生成前後の小細工はこれでできるようになりました(・∀・)
っで、次はビューのあたりの拡張ですね。


ちなみに、情報があまりまとまって存在しない感じのASP.NET MVCですが、公開されているPDFもわかりやすかったし、これでも買ってみようかな、っと思ったり。

Professional ASP.NET MVC 1.0 (Wrox Programmer to Programmer)

Professional ASP.NET MVC 1.0 (Wrox Programmer to Programmer)

4月のお金に余裕があったら…(´д`;)

*1:after Railsな皮を被った無設定Strutsを使用(・∀・)

*2:実践で使ったことはないけど、JSFも同じくらいと考えて良い?

*3:でも、.NETで行くという選択肢が無いことも無い(´ω`)