2

Mark Seemann のブログ投稿と、それを参照するこの応答を読んで、クラス コンストラクターを介した依存性注入よりもService Locatorパターンを使用することの欠点を理解しました。また、この問題について説明している Ninject、MVC 3 およびサービス ロケーター パターンの使用による依存性注入も読みました。

ただし、私の質問はこの特定のケースに関するものです。

public class MyController
{
    public void GetData()
    {
        using (var repository = new Repository())
        {
            // Use the repository which disposes of an Entity Framework
            // data context at the end of its life.
        }
    }

    // Lots of other methods.
}

ここには、内部の Entity Framework データ コンテキストを自動的にインスタンス化するリポジトリを呼び出すメソッドを含むコントローラーがあります。この単一のデータ コンテキストが使用されます。これは、コンテキストがリポジトリ内のすべてのメソッドによって呼び出されるためです。そのため、リポジトリ オブジェクトの存続期間全体にわたって単一のコンテキストを共有することが理にかなっているように思われます。

現在、コントローラ クラスが大きいため、この特定のリポジトリが使用されない可能性が高くなります。この DC のインスタンス化は高価な操作であると (おそらく間違って) 想定しているため、そうすることは避けたいと思います。サービス ロケーター パターンを使用すると、コンテキストが実際に必要になるまでインスタンス化を延期できますが、上記のリンクでそれに対する有効な引数を考えると、それを避けることをお勧めします。

したがって、私が知りたいのは、上記のケースで依存性注入を使用するより効率的な方法があるかどうかです。これにより、リポジトリと基礎となるデータ コンテキストが不必要にインスタンス化されるのを防ぐことができます。

4

3 に答える 3

2

コントローラクラスが大きいため、特定の構造で接続が使用されない可能性が高くなります。したがって、リポジトリをインスタンス化し、標準のコンストラクタベースのDIを使用して接続を開くことは意味がありません。

Lazy代わりに、、、、Funcまたはファクトリを挿入します。

public class MyController
{
    // Use constructor injection to populate this.
    private Func<MyRepository> _repository;

    public void GetData()
    {
        using (var repository = _repository())
        {
            // ...
        }
    }
}

そうすれば、必要になるまで実際のインスタンスを作成することを回避できます。

@sellmeadogの答えも良いです。

于 2013-01-03T20:35:10.300 に答える
2

答えは、リポジトリが接続を管理する方法に依存すると思います。構築時にデータベースへの接続を開く場合、問題は依存性注入ではなく、リポジトリにあると思います。リポジトリは、要求が行われたときにのみ接続を開き、応答を受信するとすぐに接続を閉じる必要があります。このパターンに従って、依存性注入は依然として理にかなっています。


更新に基づいて、EFは構築時にデータベースへの接続を開かず、要求が行われた場合にのみ、DIを使用する方がよいでしょう。データコンテキストは十分に小さいため、リクエストごとにコンテキストを作成するために必要なオーバーヘッドはわずかです。


もう1つのコメント:データコンテキストをリポジトリに挿入し、DIコンテナにコンテキストの存続期間を制御させることも検討する必要があります。これにより、1回のリクエストで1つ以上のリポジトリで同じコンテキストを使用できます。これは、ASP.NETMVCでEntityFrameworkを使用してリポジトリと作業単位のパターンを実装する方法を説明する非常に優れたリソースです。

于 2013-01-03T20:31:21.997 に答える
2

データベース接続を Repository コンストラクターに挿入する必要があるかどうかを尋ねていますか? 実際のデータベース接続の代わりにデータベース接続ファクトリーを注入するAbstract Factory設計パターンを使用してみることができます。

public class MyController
{
    public void GetData()
    {
        using (var repository = new Repository(IDatabaseConnectionFactory dbConnFac))
        {
            // Use the repository which disposes of a database connection
            // at the end of its life.
        }
    }

    // Lots of other methods.
}

このようにして、リポジトリがデータベース接続のライフサイクルを管理できるようにしながら、依存性注入の利点を得ることができます。

于 2013-01-03T20:37:56.380 に答える