normalian blog

Let's talk about Microsoft Azure, ASP.NET and Java!

 ASP.NET MVCでQuill 〜その2〜

id:waritohutsu:20090601:1243835418でASP.NET MVCQuillを使用する方法を書いたんですが、問題点がありました。実は初回リクエスト時にはインターフェースにクラスがインジェクションされるのですが、2回目のアクセスではインジェクションが失敗して、インターフェース定義のメンバ変数がNULLになります。

public class ProductController : Controller
{
    //以下みたいなのが、2回目以降のリクエストではNULLになる
    readonly ICategoryRepository<Category> categoryRepository;
    (中略)
}

[Implementation(typeof(CategoryRepository))] //本番用インジェクションクラス
[Mock(typeof(TestCategoryRepository))] //テスト用インジェクションクラス
public interface ICategoryRepository<T>
{
    IQueryable<T> GetAll();
    T GetByID(int id);
    (中略)
}

直感で、QuillInjector内部のインジェクションキャッシュが問題なのかなぁと認識したので、DefaultControllerFactoryの継承クラスを以下に変更。

public class QuillControllerFactory : DefaultControllerFactory
{
    protected QuillInjector _quillInjector = QuillInjector.GetInstance();

    public QuillInjector Injector
    {
        get
        {
            return _quillInjector;
        }
        set
        {
            _quillInjector = value;
        }
    }

    public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
    {
        IController controller = base.CreateController(requestContext, controllerName);
        _quillInjector.Inject(controller);
        return controller;
    }

    //★ここを編集&追加★
    public override void ReleaseController(IController controller)
    {
        //ここでインジェクターのキャッシュをクリア
        _quillInjector.ClearInjected();
        base.ReleaseController(controller);
    }
}

これで一応の動作を確認しました。DIコンテナに関して、AOPはいらない子だと思ってしまっている私ですが、インジェクション自体はクラスの結合を疎にできるので悪くはないかと。

しかし、これはちょっとパワーに過ぎるなぁ…(性能問題とか余裕で起きそうだし)。ちょっと暫定対策を打っただけなので、なんで2回目以降にインジェクションを失敗するのかちゃんと調べよう。どうせリフレクションでインスタンス生成した場合では〜的な話だと思うけど。