2012-05-09 13 views
0

私はMVC 3アプリケーションで常にNinjectを使用しますが、UnitOfWorkを使用するデータオブジェクトのパターンを変更しようとしています。これを適切に処理するためにNinjectを取得する方法がわかりません。Ninject UnitOfWorkの混乱

私は彼らが私のコンソールアプリケーションでは、次のように手動で構成されたときにクラスの私の実装は仕事を知っている:私のMVC 3アプリケーションで

IDatabaseFactory factory = new DatabaseFactory(); 
IUnitOfWork worker = new UnitOfWork(factory); 
IBlogCategoryDao dao = new BlogCategoryDao(factory); 
IBlogCategoryService service = new BlogCategoryService(dao); 

BlogCategory category = service.GetById(id); 

try 
{ 
    if (category != null) 
    { 
    service.Delete(category); 
    worker.Commit(); 
    Console.WriteLine("Category deleted successfully!"); 
    } 
    else 
    { 
    Console.WriteLine("Entity doesn't exist."); 
    } 
} 
catch (Exception ex) 
{ 
    Console.WriteLine("Error deleting category: {0}", ex.Message); 
} 

私はNinject.MVC3 NuGetパッケージを使用していて、これはですRegisterServicesメソッド

private static void RegisterServices(IKernel kernel) 
{ 
    kernel.Bind<IDatabaseFactory>().To<DatabaseFactory>(); 
    kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope(); 

    kernel.Bind<IBlogCategoryDao>().To<BlogCategoryDao>(); 
    kernel.Bind<IBlogDao>().To<BlogDao>(); 

    kernel.Bind<IBlogCategoryService>().To<BlogCategoryService>(); 
    kernel.Bind<IBlogService>().To<BlogService>(); 
} 

ほとんどの場合、Get要求ですべてのPOST要求(Insert、Update、Delete)が実行されません。スローされた例外はありません。スクロールすると、問題なくSaveChanges()メソッドを実行し、スタックを戻しますが、何も実行されません。だから私は自分のNinject設定で何かが欠けているに違いないことを知っている。

私の作業単位クラスは次のとおりです。

public class UnitOfWork : IUnitOfWork 
{ 
    private Database _database; <-- DbContext derived class 

    private readonly IDatabaseFactory _databaseFactory; 

    public UnitOfWork(IDatabaseFactory databaseFactory) 
    { 
     this._databaseFactory = databaseFactory; 
    } 

    public Database Database 
    { 
     get 
     { 
      return _database ?? (_database = _databaseFactory.Get()); 
     } 
    } 

    public void Commit() 
    { 
     Database.Commit(); 
    } 
} 

ここDatabaseFactoryクラスです:

public class DatabaseFactory : Disposable, IDatabaseFactory 
{ 
    private Database _database; 

    public DatabaseFactory() 
    { 

    } 

    public virtual Database Get() 
    { 
     if (_database == null) 
     { 
      _database = DataObjectFactory.CreateContext(); 
     } 

     return _database; 
    } 

    protected override void DisposeCore() 
    { 
     if (_database != null) 
     { 
      _database.Dispose(); 
     } 
    } 
} 

そして、私のDataObjectFactoryクラス:

public static class DataObjectFactory 
{ 
    private static readonly string _connectionString; 

    /// <summary> 
    /// Static constructor. Reads the connectionstring from web.config just once. 
    /// </summary> 
    static DataObjectFactory() 
    { 
     string connectionStringName = ConfigurationManager.AppSettings.Get("ConnectionStringName"); 
     _connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString; 
    } 

    /// <summary> 
    /// Creates the Context using the current connectionstring. 
    /// </summary> 
    /// <remarks> 
    /// Gof pattern: Factory method. 
    /// </remarks> 
    /// <returns>Action Entities context.</returns> 
    public static Database CreateContext() 
    { 
     return new Database(_connectionString); 
    } 
} 

これはEFMVC CodePlexのアプリケーションで使用されるのと同様のパターンであるが、私は使用しませんオートファック。

これについてのご意見はありがたいです。

ありがとうございました。

+0

データベースとは何ですか?これはあまりにも複雑なようです。 –

+0

データベースはDbContextの派生クラスです。 IDbSet プロパティが含まれています。 – Kahanu

+0

私は実際にそれを少しリファクタリングして動作させました。私はDatabaseFactoryクラスを完全に削除し、代わりに具体的なリポジトリクラス(BlogCategoryDao)にUnitOfWorkインスタンスを注入しています。 BlogCategoryDao(IUnitOfWork)。これははるかに優れたクリーナーです。実際に動作します! – Kahanu

答えて

4

私はこれを行う:

kernel.Bind<IUnitOfWork>.To<EFUnitOfWork>().InRequestScope(); 

EFUnitOfWork.cs

public class EFUnitOfWork : DbContext, IUnitOfWork 
{ 
    // your normal DbContext plus your IUnitOfWork members that delegate to EF context 
} 

EFが既に作業単位の形式を実装しているので、これはあなたがそれのために、より汎用的なインタフェースを使用することができます、とそれを簡単に注入する。

また、接続文字列のEFコンストラクタを実装して、それらをベースコンストラクタに渡すこともできます。次に、Ninject .WithConstructorArgument()を使用して、AppSettingsコードを使用して接続文字列を構成できます。

+0

.InRequestContext()拡張子が表示されません。 .InRequestScope()ですか?私はそれを有効にしてあり、それはまだ動作しません。 – Kahanu

+0

@カハヌー - はい、申し訳ありませんが、それを忘れてしまいました。 –

+1

私は非常に似た問題に直面していました。私は、InRequestScopeをninjectのカーネルのDbFactoryバインディングに追加しました。 –