2016-03-25 6 views
1

asp.net mvc-4 Webアプリケーションとエンティティフレームワーク5.0で作業しています。 Disposeがアプリケーション内でどのように動作しているのか混乱しています。現在、次の設定があります。 -Dispose()がControllerクラスとRepositoryクラス内でどのように動作するか

- 私は外部API呼び出しを行うためにWebClient()を使用する複数のメソッドを含むAPIRepositoryクラスを持っています。私はこのクラスの中にDisposeメソッドを定義していません。

public class APIRepository 
     { 

      public string AddTicket(string title, string technichian,string account,string site,string description,string mode,string requestor) 
      { 

       //code goes here 

         using (var client = new WebClient()) 
         { 
         } 
        return result; 
      } 
//code goes here 
     } 

-I私のデータアクセスロジックが含まれているリポジトリのクラスを持っている、そしてそれは私のDbContextを開始し、私はこのクラス内のDisposeメソッドを定義します。

public class Repository 
{ 

     private MyEntities my = new MyEntities(); 
//code goes here... 
     public void Dispose() 
     { 
      my.Dispose(); 

     } 

-I 2つのリポジトリのクラス開始Controllerクラス、している: - :

に基づいて
  1. -

    [RequireHttps] 
    
    public class ServerController : Controller 
    { 
    
         Repository repository = new Repository(); 
         APIRepository APIrepository = new APIRepository(); 
    
    //code goes here 
         protected override void Dispose(bool disposing) 
         { 
          if (disposing) 
          { 
           repository.Dispose(); 
    
          } 
          base.Dispose(disposing); 
         } 
    

    は今、私は私の現在のプロジェクトについて、以下の質問を持っていますDisposeの仕組みに関する私の理解は、アクションメソッドがViewを呼び出すと、asp.net mvcは現在のControllerクラス内のDisposeメソッドを自動的に呼び出します。リポジトリ内のDisposeメソッドを呼び出し、データベース接続が閉じられていることを確認します。私の理解は有効ですか?

  2. 私の場合、私のAPIRepository()内にDisposeメソッドが必要ですか?私はこのリポジトリにはサードパーティアプリケーションとの統合を呼び出すWebClient()コールがあり、アクションに単純な文字列を返します方法。??

  3. 処分する必要がある操作は何ですか?私のリポジトリクラス内にmy.Dispose();を呼び出すと、データベース接続が閉じられていることがわかりますが、他の処理が必要ですか? WebClient()を開始するか、アクションメソッドでJSONを返すなどの方法がありますか?

  4. Viewを返す以外のアクションは、Controllerクラス内でDisposeメソッドを呼び出しますか?データベース接続が閉じていることを確認します

+3

私はこのサイトで検索して、あなたの質問に対するすべての回答を見つけることができます。多分、いくつかの質問で分かれています。 –

+1

あなたは 'IDisposable'から継承しているようには見えません – Jonesopolis

+0

@ Jonesopolis ServerControllerクラスはControllerクラスを拡張しました。そしてControllerクラスはIDisposableインターフェイスを実装しています(これらは、新しいControllerクラスを作成するときにasp.net mvc内のボックスから実行されます)。その後、ServerController内部でDisposeメソッドをオーバーライドしています。 「あなたがIDisposableから継承しているとは思われません」ありがとうございました –

答えて

2

。私の理解は有効ですか?

データベース接続は、disposeメソッドが呼び出される前に閉じられています。それはそうではない非常にまれな状況です。私の場合は

私は(私のAPIRepository内のDisposeメソッドを持っている必要があります)

あなたの代わりに、メソッドレベルのフィールドレベルでのオブジェクトの使い捨てを管理している場合のみ。

// The method is disposing of the object 
public class NotDisposable 
{ 
    public string GetString() 
    { 
    string result; 
    // This is disposed by the time the method exists. 
    using(var disposable new Disposable) 
    { 
     result = disposable.GetString() 
    } 
    return result; 
    } 
} 

// This class has a field that it needs to dispose 
// so it inherites from IDisposable 
public class Disposable : IDisposable 
{ 
    private bool _isDisposed; 
    private readonly IDisposable _somethingToManuallyDispose; 

    public Disposable() 
    { 
    somethingToManuallyDispose = new SomethingImplementsIDisposable(); 
    } 

    public void Dispose() 
    { 
    Dispose(true); 
    GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
    if (disposing && !_isDisposed) 
    { 
     _isDisposed = true; 
     // Dispose Managed Resources 
     if (_somethingToManuallyDispose != null) 
     { 
     _somethingToManuallyDispose.Dispose(); 
     } 
    } 
    } 
} 

が、廃棄する必要がある他の操作がありますか?

上記の例では、メソッドにオブジェクトを破棄しません。

文も意味がありませんViewは私のコントローラクラスの内部でDisposeメソッドを呼び出します

を返す以外の行為は何ですか。ビューを返してもDisposeは呼び出されません。 MVC/APIパイプラインクライアントに応答が送信された後で、コントローラがIDisposableを実装している場合に限り、コントローラを破棄します。

MSDN - Dispose PatternMSDN - Implementing a Dispose MethodMSDN - Using Objects That Implement IDisposableとお考えください。

+0

あなたの返信に感謝します..しかし、私は私たちの返信にこれらの質問があります1)どういう意味ですか?「メソッドレベルの代わりにフィールドレベルでオブジェクトの使い捨てを管理している場合のみ」 2番目の質問は私の現在の実装では、ServerControllerクラスは、コントローラを拡張し、コントローラがIDisposableインターフェイスを実装する(これはボックスasp.net mvcによって行われます)、私の場合は、ServerController内のDisposeメソッドをオーバーライドしている私の場合はどのように処理するのですか?私のアプローチが正しいのか間違っているのか分かりません。 –

4

依存関係注入を使用している場合は、いずれのクラスも、またはを作成する責任はありません。

の代わりにこの:

public class ServerController : Controller 
{ 
    private readonly Repository _repository; 
    private readonly APIRepository _apiRepository; 

    public ServerController(Repository repository, APIRepository apiRepository) 
    { 
     _repository = repository; 
     _apiRepository = apiRepository; 
    } 

ServerControllerのインスタンスを作成し、何でもそれらのオブジェクトをインスタンス化する責任がある:ServerControllerはその依存関係を作成し、それらを処分する責任があり、これは

public class ServerController : Controller 
{ 
    Repository repository = new Repository(); 
    APIRepository APIrepository = new APIRepository(); 

それらの処分。それはウィンザーやユニティのような、あなたの依存性注入容器です。それとも、ASP.NET Coreに組み込まれているので、別のコンテナを追加する必要はありません。

短いバージョン:コンテナはリポジトリを作成し、処分する必要がある場合は処分します。特定の依存関係の存続期間に関する詳細を指定することもできます。それが使い捨てではなく、再利用できるのであれば、それはシングルトンです。新しいインスタンスは、必要なときにいつでも作成して廃棄することができます。または、指定されたWebリクエストに関連付けられた新しいインスタンスを作成できます。その要求はそれを使用し、それが破棄されます。

+0

返信ありがとう、今私の場合私は依存性注入を使用していない、私はリポジトリメソッドクラスを使用しているので、あなたはどのように私のディスポーザルの仕事をアドバイスすることができますか?私のアプローチがオブジェクトを処分しないと言っているのかどうかはわかりません。 –

+1

リポジトリと依存性注入は排他的でも矛盾していません。あなたのクラスにレポジトリを作成すると、そのリポジトリを破棄できますが、リポジトリを破棄する必要があります。依存関係注入を使用すると、あなたのリポジトリが作成され、コンストラクタの引数として「注入」されます。コントローラーはそれを使用しますが、コントローラーを作成または廃棄する責任は負いません。実際には、「私の問題ではなく、私に必要なものを与えてください」と言っています。 DIコンテナを使用している場合は、リポジトリを作成して、コントローラが有効範囲外になったときに処分することができます。 –

+1

ここではWindsorを使ったチュートリアルを開始します。 https://github.com/castleproject/Windsor/blob/master/docs/basic-tutorial.md。 DIは数年前に同僚が私にそれを紹介したとき、完全に外国人だった。それは私のための巨大な "電球"の瞬間でした。 DIコンテナ自体を使ってすべてを解決するのではなく、クラスを作成する方法を変えました。また、単一責任クラスや制御の逆転などのベストプラクティスを促進し、奨励します。それは触媒のようなもので、他の多くのものに意味を持たせました。私はそれをうんざりしていますか?それは素晴らしいです。 –

関連する問題