2011-12-29 10 views
1

私はMVVMを持つWPFアプリケーションを持っています。 ViewModelにからオブジェクト構成を以下のように見えるダウンと仮定:作業ユニットとしてのNinject ActivationBlock

MainViewModel 
    OrderManager 
     OrderRepository 
      EFContext 
     AnotherRepository 
      EFContext 
    UserManager 
     UserRepository 
      EFContext 

私の独創的なアプローチは、他のすべてのために)EFContextと.InTransientScope(上.InCallScopeを()を使用して、私のビューモデルに(ViewModelLocatorから)依存性を注入することでした。その結果、最終的に同じEntity Framework Contextを共有する複数のビジネスレイヤオブジェクト(Managers)にわたって「ビジネストランザクション」を実行できるようになります。単なる作業単位のシナリオでは、私は単純にCommit()のコンテキストを最後に述べます。

これは、ビューモデルレベルで長いリビングエンティティフレームワークコンテキスト、複数の操作でのデータ整合性の問題HEREが必要でないことがわかるまで、意図どおりに機能しました。私は私のEntity Frameworkコンテキストのために.InRequestScope()を使う私のWebプロジェクトに似た何かをしたいです。デスクトップアプリケーションでは、ビジネストランザクションとして機能する作業単位を定義します。通常は、ボタンクリックや同様のイベント/コマンド内ですべてをラップします。 NinjectのActivationBlockを使用すると、私のためにこれを行うことができるようです。私のコードで

internal static class Global 
{ 
    public static ActivationBlock GetNinjectUoW() 
    {    
     //assume that NinjectSingleton is a static reference to the kernel configured with the necessary modules/bindings 
     return new ActivationBlock(NinjectSingleton.Instance.Kernel); 
    } 
} 

私はそのように使用する:

//Inside a method that is raised by a WPF Button Command ... 
using (ActivationBlock uow = Global.GetNinjectUoW()) 
{ 
    OrderManager orderManager = uow.Get<OrderManager>(); 
    UserManager userManager = uow.Get<UserManager>(); 

    Order order = orderManager.GetById(1); 
    UserManager.AddOrder(order); 
    .... 
    UserManager.SaveChanges(); 
} 

質問:これは私がウェブ上でビジネスを行う方法を複製するようで、私に

  1. があり、私が逃したこのアプローチに本質的に何も間違っていますか?
  2. アクティベーションブロックを使用しているすべての.Get <が、そのブロックのローカルで "シングルトン"を生成することを正しく理解していますか?つまり、何度もOrderManagerを要求しても、ブロック内で常に同じものが表示されます。 OrderManagerとUserManagerが同じリポジトリを(例えばSpecialRepositoryと)リポジトリを構成する場合、どちらもリポジトリの同じインスタンスを指しており、下のすべてのリポジトリはEntity Frameworkコンテキストの同じインスタンスを共有していることは明らかです。

答えて

2

両方の質問はイエスと答えたことができます。

  1. はい - これはサービスあなたが
  2. を行うべきではありませんはい、あなたがそれを理解した場所に正しく
+0

はい、私はそれを知っている、しかし、私は他の選択肢が表示されません。より良い提案はありますか? – e36M3

+0

usingブロックの内容を含むクラスを作成し、ファクトリを使用してそのインスタンスを作成し、EFコンテキストをInCallScopeに配置します。 –

+0

これは、私のWPFウィンドウが3つのブロックを使用する場合、必要なビジネスレイヤクラスと各セットのファクトリを含む3つのクラスが必要になることを意味します。私はViewModelが直接ninjectと対話する必要はないので、より洗練されていると理解していますが、生産性向上のためにこのヒットを受け入れる意思があります。ビジネス層のダウンは気にならないでしょうビューモデル。私が間違っていると誤解していない限り、私を修正してください。 – e36M3

0

適切な手段 - 前記ありますNinject.Extensions.UnitOfWorkに実装されている作業範囲はこの問題を解決します。

セットアップ:

_kernel.Bind<IService>().To<Service>().InUnitOfWorkScope(); 

使用法:

using(UnitOfWorkScope.Create()){ 
    // resolves, async/await, manual TPL ops, etc  
} 
関連する問題