2

Ninject.Web.Mvc2とリポジトリパターン(エンティティフレームワークモデル上に構築された)を使用するMVC2.0アプリケーションがあります。リクエストの期間中のみ存続する新しいObjectContextを作成しようとしています。私はこれを次の方法で達成しようとしています:

protected override IKernel CreateKernel(){
    var kernel = new StandardKernel();
    kernel.Load(Assembly.GetExecutingAssembly());
    return kernel;
}

    protected override void OnApplicationStarted()
    {
        AreaRegistration.RegisterAllAreas();
        RegisterRoutes(RouteTable.Routes);
    }

次に、この汎用性を十分に維持するためのアイデアが不足したため、BeginRequestで作業するように設定しました。

    protected void Application_BeginRequest()
    {
         string EntityConnectionString = ConfigurationManager.ConnectionStrings["Entities"].ConnectionString;
         HttpContext.Current.Items.Add(_PerRequestContextObjectKey, new EntityFrameworkContextWrapper(EntityConnectionString));
         this.Kernel.Bind<IUserRepository>().To<UserRepository>().WithConstructorArgument("ContextWrapper", HttpContext.Current.Items[_PerRequestContextObjectKey]);
    }

Wrapperクラスは、リクエストの最後に強制終了したいものをすべて含めるための単なる汎用オブジェクトです。この特定のケースでは、これを使用して新しいObjectContextを作成し、IDisposableを実装して、次のことを実行できるようにします。

    protected void Application_EndRequest()
    {
        foreach (var Item in HttpContext.Current.Items)
        {
            if (Item.GetType() == typeof(IPerRequestLifetimeObjectWrapper))
            {
                (Item as IPerRequestLifetimeObjectWrapper).Dispose();
            }
        }
    }

これを行うのに最も美しい方法ではないと確信していますが、これらすべてのことを「学ぶ」ことに多くの時間を費やしてきたので、この時点で私は動こうとしています。

次に、私のコントローラーは次のように注入されます。

public class AdminUserController : Controller
{
    // Mark for Ninject
    [Inject]  public IUserRepository _userRepo { get; set; }

    public ViewResult Index( )
    {
        return View(_userRepo.Get);
    }

    public ViewResult Edit(Guid UserUID)
    {
        return View(_userRepo.GetById(UserUID));
    }
}

そして私のリポジトリも注入されます:

    [Inject]
    public UserRepository(EntityFrameworkContextWrapper ContextWrapper )  
        // Mark for Ninject Dependency Injection 
        // Must receive Wrapper that contains active ObjectContext
    {
        _db = ContextWrapper.Entities;  //Not actually named this, just easier for typing right now
    }

コントローラがUserRepositoryオブジェクト内のGetメソッドを初めて呼び出すと、正常に機能します。更新を押すと(またはポストバックも推測します)、_dbはNullになります。デバッガーをステップスルーしようとすると、Application_BeginRequest()が呼び出される前にController Index()メソッドが呼び出されていることがわかります。「パイプライン」(WebFormsからページライフサイクルと呼ぶことに慣れている)については理解していると思いましたが、今は少し迷っています。誰かが私の脳がいくつかのワイヤーを交差させている場所について詳しく説明できますか?私が言ったように、これはおそらく最も美しい方法ではありませんが、MVC、Ninjectを使用したDI、リポジトリ、およびEntity Frameworkを学ぶのに約1週間半しかありませんでしたので、話しているように感じないでください私が非常に基本的な何かを壊したように思えるなら、私には。

4

1 に答える 1

1

単純に InRequestScope を使用してみませんか? あなたがすることは、リクエストごとに新しいバインディングを追加することです。これは深刻な問題につながります。https://github.com/ninject/ninject.web.mvc/wiki/Unit-of-work-pattern-with-nhibernateを参照してください

それはNHilbernateですが、EntityFrameworkでも同じことができます

于 2011-04-25T20:36:40.383 に答える