オブジェクトの編集と削除に問題があります。リポジトリクラスとunitofworkクラスの間で同じセッションオブジェクトを共有していないためだと思います。同じセッションオブジェクトを共有するために、これを接続するための最良の方法に関するドキュメントを見つけようとしています。
mvcWebサイトでIOCコンテナーとしてninjectを使用しています。
オブジェクトの編集と削除に問題があります。リポジトリクラスとunitofworkクラスの間で同じセッションオブジェクトを共有していないためだと思います。同じセッションオブジェクトを共有するために、これを接続するための最良の方法に関するドキュメントを見つけようとしています。
mvcWebサイトでIOCコンテナーとしてninjectを使用しています。
私は通常、セッションをリポジトリの依存関係として設定するので、Ninjectは依存関係を解決できます(ISession = NHibernate.ISession):
public UserRepository(ISession session)
{
...
}
これが私がバインディングを設定する方法です:
kernel.Bind<ISession>().ToMethod(x => GetRequestSession()).InRequestScope();
したがって、セッションが必要な場合、NinjectはGetRequestSession()を呼び出してセッションを取得します。この関数は次のように実装されます。
private static ISession GetRequestSession()
{
IDictionary httpContextItems = HttpContext.Current.Items;
ISession session;
if (!httpContextItems.Contains(MvcApplication.SESSION_KEY))
{
// Create an NHibernate session for this request
session = MvcApplication.SessionFactory.OpenSession();
httpContextItems.Add(MvcApplication.SESSION_KEY, session);
}
else
{
// Re-use the NHibernate session for this request
session = (ISession)httpContextItems[MvcApplication.SESSION_KEY];
}
return session;
}
NHibernateセッションはHttpContextアイテムに保存されます。これは、1つのリクエストの処理中にデータを保存および共有するために使用できるKey-Valueコレクションです。
セッションはリクエストごとに1回だけ作成され、リクエスト中に再利用されます。
MvcApplication.SESSION_KEYは、HttpContextからセッションを保存および取得できるようにするために、Global.asaxで定義した定数文字列です。また、セッションファクトリはglobal.asaxにあり、起動時に作成されます。
作業単位クラスがISessionを依存関係として設定することもできるため、Ninjectもこの依存関係を解決し、同じセッションを使用します。一方、NHibernateのISession自体の実装はすでに作業クラスの単位であるため、作業クラスの単位は必要ない場合があります。
これがベストプラクティスかどうかはわかりませんが、私にとっては完璧に機能します。
Nhibernateには、セッション、つまりコンテキストを共有するためのメカニズムが組み込まれています。アプリケーションに基づいて、適切なコンテキストを使用できます。詳細については、
http://nhibernate.info/doc/nhibernate-reference/architecture.html#architecture-current-session
ロビンの答えがうまくいかない場合は、Ninjectの設定が間違っている可能性があります。
私は今朝、アップデートで非常によく似た問題に遭遇しました。私の場合、書き込み先のセッションとは異なるスコープのオブジェクトにバインドされたセッションからオブジェクトを読み取っていました。
これが私の単純なSessionProviderです。
public class SessionProvider : Provider<ISession>
{
protected override ISession CreateInstance(IContext context)
{
var factory = context.Kernel.Get<ISessionFactory>();
var session = factory.OpenSession();
return session;
}
}
およびIOCコード:
kernel.Bind<ISessionFactory>().ToProvider<SessionFactoryProvider>();
kernel.Bind<ISession>().ToProvider<SessionProvider>().InRequestScope();
作業ユニットとリポジトリの両方が同じISessionでインスタンス化されるようにする最も簡単な方法は、両方がリクエストスコープで作成されるようにすることです。ただし、これがデフォルトである必要があります。
NInjectのインストール方法と使用しているバージョンによっては、Requestスコープが正しく機能するようにHTTPモジュールをインストールする必要がある場合があります。
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
<add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/>
<add name="OnePerRequestHttpModule" type="Ninject.Web.Common.OnePerRequestHttpModule, Ninject.Web.Common"/>