2

建築上の問題。私は、かなりうまく機能しているいくつかのプロジェクトを備えた、うまく分離された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には属していません。すべてに依存する独自のプロジェクトが必要ですか、それともより良い方法がありますか?

4

1 に答える 1

3

私はあなたが必要とする追加のサービスのためにある種の自動車工場を使うでしょう。PostServiceしたがって、コンストラクターは次のように記述します。

public PostService( Func<INeededService1> factory1,Func<INeededService2> factory2 ...)
{
...
}

次に、この拡張機能を使用して、これらのファクトリを自動的に機能させます(コンテナにクエリを実行することにより)。

于 2012-06-13T10:24:18.330 に答える