読者です 読者をやめる 読者になる 読者になる

割と普通なブログ

Microsoft Azure や ASP.NET、Java EE 系の話題を記載します

 ASP.NET MVCでQuill 〜その2〜

C# Seaser.NET ASP.NET MVC

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回目以降にインジェクションを失敗するのかちゃんと調べよう。どうせリフレクションでインスタンス生成した場合では〜的な話だと思うけど。