建築上の問題。私は、かなりうまく機能しているいくつかのプロジェクトを備えた、うまく分離されたMVC3ソリューションを持っています。
Proj.Core - interfaces for data classes and services Proj.Services - interfaces for model services Proj.Data.NH - implementations of the data interfaces Proj.Services.NH - implementations of the data / model services Proj.Infrastructure - setting up Ninject and NHibernate Proj.Tests - unit tests Proj.Web - the MVC project
インフラストラクチャプロジェクトでリクエストごとにセッションになるようにNHibernateを設定したので、Proj.WebはNHibernate(またはNinject)を参照する必要はありません。クイックチャットアプリに非常に適したSignalRを紹介します。私はSignalRハブをWebプロジェクトに配置しました。チャットメッセージをデータベースに保持したいので、少し混乱しました。
サービスを使用したいので(それを呼びましょうPostService
)、SignalRハブはNHibernateに依存していません。私の他のサービスはコントローラーのコンストラクターに注入され、セッションはサービスのコンストラクターに注入されます。
コントローラーとは異なり、SignalRハブがハングしているため、PostService
(コンストラクターにとして挿入されたIPostService
)セッションをコンストラクターに挿入することはできません。これは、セッションが存在しないためです。もしあったとしたら、それは永遠にぶらぶらしていて、それは取引には長すぎるでしょう。
セッションファクトリをに注入することができPostService
、各メソッドはトランザクションを使用できます。
private void WithTransaction(Action<ISession> action)
{
using (var session = _sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
action(session);
tx.Commit();
}
}
public IPost Post(string message)
{
WithTransaction(session =>
{
session.Save(new Post(message));
});
}
その後、ハブは呼び出します_postService.Post(message);
ただし、Post
メソッドがさらに多くのことを実行したら、既存のサービスのいくつかを使用して実行したいと思います。これらのサービスは既に作成され、単体テストされているためです。PostService
セッションはメソッドで作成されるため、コンストラクターへのセッションを受け入れるため、コンストラクターにサービスを注入することはできません。
したがって、次のオプションがあると思いますが、a)これが完全なリストであるか、b)これが最良のオプションであるかはわかりません。
I.コンストラクターにIDependencyResolver
を挿入しPostService
、メソッドで必要なサービスを作成してPost
、セッションをコンストラクターに渡します。System.Web.MvcとSignalRにあるIDependencyResolver
ので、これは(どのプロジェクトがPostService
存在するかに応じて)どちらかのライブラリへの依存関係を導入します。
II。セッションを使用する各メソッドがパラメーターとして渡されるようにサービスを変更します。セッションパラメータなしでこれをオーバーロードし、新しいパラメータを呼び出します。MVCサービス呼び出しは最初のものPostService
を使用し、2番目のものを使用します。
public void SaveUser(IUser user)
{
Save(_session, user);
}
public void SaveUser(ISession session, IUser user)
{
session.Save(user);
}
III。既存のサービスを使用しないでください。PostService
少し重複している場合でも(ユーザーの詳細を取得するなど)、独自のことを実行してください。
IV。サービスのコンストラクターからISessionを削除し、それを各メソッドに渡します(それにController
応じてs'を処理します。
V.何か他のもの。
私は最初のものに傾いていると思いますが、どこPostService
に住むかはわかりません。Proj.Services.NHに入る場合は、System.Web.MvcまたはSignalRへの依存関係を導入する必要がありますが、これは実行したくありません。それがProj.Webにある場合は、NHibernateへの依存関係を導入する必要がありますが、これもやりたくありません。アプリケーションコードであるため、Proj.Infrastructureには属していません。すべてに依存する独自のプロジェクトが必要ですか、それともより良い方法がありますか?