10

ASP.NET MVCアプリケーションには、すべてのビジネスロジック/サービスレイヤーを含むプロジェクトがあります。このプロジェクトは、別のプロジェクトにある私のデータベース(エンティティフレームワーク)と相互作用します。

サービスレイヤーに簡単にアクセスできるようにしたかったので、簡単に参照できるように静的クラスを作成しました。たとえば、コントローラーを使用していて、新しいアカウントを作成する必要がある場合:

 ServiceLayer.Accounts.CreateAccount(userName, passWord) //etc..

次に、サービスレイヤーは必要なすべてのロジックを実行し、のリポジトリを介してユーザーを作成しますDatabaseLayer

    private static AllRepos _Repos;
    private static AllRepos Repos { 
       get 
        { 
           if(_Repos == null)
              _Repos = new AllRepos();

           return _Repos
        }
    }

    public static void CreateAccount(string username, password)
    {
        string salt = GenerateSalt();
        Account newAccount = DatabaseLayer.Models.Account
              { 
              Name = username,
              Password = HashPassword(password, salt),
              Salt = salt
              };
        Repos.AddAccount(newAccount);      
    }

サービスレイヤーのどこでも次のことをしたくなかったからです。

 AccountRepository Accounts = new DatabaseLayer.AccountRepository();

代わりに、リポジトリのラッパークラスを作成したので、他のすべてのリポジトリを使用するには、一度だけインスタンス化する必要があります。

 public class AllRepos
 {

    private AccountRepository _Accounts;

    public AccountRepository Accounts
    {
        get
        {
            if (_Accounts== null)
                _Accounts= new AccountRepository();

            return _Accounts;
        }
    }

    // the same is done for every other repository (currently have about 10+)
  }

これは、サービス層の静的クラスで使用されました。

すべてのサービスレイヤークラスが静的であり、Reposフィールドも静的であるため、私が遭遇し続ける明らかな問題は、同じオブジェクトが複数のデータコンテキストから取得され、更新/削除の奇妙な動作を引き起こすことです。

ServiceLayer.Accounts.Method()アプリケーションのライフサイクルが続くので、静的メンバー/クラスを使用する場合はこれが予想されることを理解していますが、非静的クラスを作成せずにサービスレイヤーを使用できる方法はありますか?使用するすべての場所でインスタンス化する必要があり、複数のデータコンテキストインスタンスが原因でCRUDの問題が発生しないようにする必要がありますか?

4

4 に答える 4

16

これに対するあなたのアプローチは、実際には推奨されるものではありません。個人的には、この種のアプローチをチームに許可することは決してありません。欠点:

  1. あなたが経験しているように、解決するのは簡単ではない主要なスレッドの問題
  2. これを簡単にテストすることはできません。
  3. データアクセスの非現実的な抽象化

リポジトリのインスタンスを作成する最大の理由は、必要に応じて依存関係を挿入できるようにするためです。これについて最もよく知られている議論は、依存関係をモックできるように単体テストに関するものですが、本番コードで変更されるインターフェイスの依存関係を持つリポジトリをいくつか構築しました。

とにかく、基本サービスクラスの一部としてリポジトリのインスタンス化を行う必要があります。「どこでも静的ORインスタンス呼び出し」である必要がある理由はありません。基本クラス内には、インスタンスのインスタンス化コードが制限されている必要があります。

于 2010-02-17T19:46:06.787 に答える
10

インスタンスの使用になぜそんなに行き詰まっているのかわかりません。現在のコードは不必要に複雑であるという事実は別として、静的型を使用すると単体テストが難しくなります。静的タイプは、モック/置換できないシングルトンのようなものです。あなたの本当の質問は、「サービスレイヤーのインスタンスを生涯管理するにはどうすればよいですか?」ということかもしれません。通常、これを行うには、Webリクエストごとに1つのインスタンスを作成します。ASP.NET MVCアプリケーションでは、ControllerFactoryを介してDIコンテナーを新規作成し、これらすべてを処理できます。[PDF]

于 2010-02-17T19:45:07.553 に答える
1

作業単位パターンを実行するなど、意図的な方法でオブジェクトコンテキストのスコープを処理する必要があります

それとは別に、すべてを静的に行うことを再検討する必要があると思います。wompは、結合度が非常に高く、テストが非常に困難であり、IOCコンテナーを使用して依存関係グラフを管理するのに多くの助けを得ることができるからです。

私はこれを言うことができます、以前にそのようなことをして自分自身を燃やしたことがあります:)

于 2010-02-17T20:03:05.687 に答える
-4

シングルトン(および説明されている静的クラス)は悪であり、特にWebアプリでは絶対に避ける必要があります。

于 2010-02-17T20:09:50.990 に答える