1

私はDIを初めて使用し、コントローラーにUnitOfWorkが注入され、このUnitOfWorkにドメイン内の各エンティティタイプのリポジトリが含まれるMVCプロジェクトに取り組んでます。ガイドとしてMSDNを使用して、私はもともと次のようなものを持っていました

public IRepository<Employee> Employees {
    get {
        if (_employees == null) {
            _employees = new SqlRepository<Employee>(_context);
        }
        return _employees;
    }
}

ただし、リポジトリを挿入するとよいと思いました。たとえば、次のようになります。

public SqlUnitOfWork(IRepository<Employee> employees)
{
    this.Employees = employees;
}

しかし、SqlRepositoryの作成に非常に費用がかかる場合はどうでしょうか。すべてのコントローラーアクションがすべてのリポジトリを使用するわけではありません。DIに変更する前は、各リポジトリはアクセスされた場合にのみ作成されていました。ただし、現在、すべてのリポジトリはUnitOfWorkで作成されています。すでにSqlUnitOfWorkにいるときに、SqlRepositoriesを挿入する価値があるかどうかを判断しようとしていますか?または、MSDNの例に従う必要がありますか?

4

3 に答える 3

1

私は ASP.NET MVC ユーザーではありませんが、依存性注入アプローチの背後にある考え方は変わりません。だから、これを一粒の塩で取ってください。

あなたの説明から、作業単位でいくつかのリポジトリを使用しており、それらを注入するか、作成するかを決定できません。最良のコースは次のとおりです

不明な数の同じタイプの依存関係を扱っている場合は、代わりにファクトリ インスタンスを注入する方が賢明です。実装UnitOfWorkは、そのファクトリからサービスを要求できます。

この場合、ファクトリは、そのようなサービスが既に初期化されているかどうかを確認します。そのようなサービスが初期化されている場合は、それを返すことができます。そうでない場合は、そのサービスを初期化し、キ​​ャッシュして(ほとんどの場合、ファクトリ内の配列のような構造に)、そのインスタンスを返します。


その他の注意事項

  • リポジトリも作業単位もコントローラーに公開しないでください。それらは、ストレージの処理を担当する構造です。モデル層の内部の詳細をプレゼンテーション層に公開することになります。基本的に、あなたの抽象化はleakingです。

  • 私はそのチュートリアルを読むことに注意します。この記事の著者は、DI の概念を十分に理解していなかったようです。このコードを見ると、次のようになります。

    public class SqlUnitOfWork : IUnitOfWork {
        public SqlUnitOfWork() {
            var connectionString =
                ConfigurationManager
                    .ConnectionStrings[ConnectionStringName]
                    .ConnectionString;
            _context = new ObjectContext(connectionString);
        }
    
        /* --- SNIP --- */
    
        readonly ObjectContext _context;
        const string ConnectionStringName = "EmployeeDataModelContainer";
    }
    

    SqlUnitOfWorkクラスの定義に組み込まれている定数に基づいて、コンストラクターで DB 接続が初期化されていることがわかります。それは非常に悪い習慣です。

  • 一般的な OOP プラクティスの依存性注入について詳しく知りたい場合は、この講義と同じシリーズの講義を視聴することをお勧めします。

于 2012-09-24T23:20:16.543 に答える
0

作成に費用がかかるオブジェクトを注入することについて心配するのは当然です。

依存性注入は、オブジェクトを安価に作成および注入できることに依存しています (その一部は決して使用されない可能性があります)。これが、コンストラクターで、またはオブジェクト グラフを作成するときに「実際の作業」を実行するのが悪い考えである理由です。

ここでの問題は、IRepository作成に費用がかかることです。コンストラクターで「実際の作業」を行っている場合、その作業を後で必要になる直前に移動できますか? これは遅延評価に少し似ています。これにより、問題の根本原因が修正されます。

時々、それは不可能です。回避策があります:

  • IRepository (ファクトリー) のインスタンスを提供するものを注入します。
  • IRepository インターフェースを LazyRepository として実装します。LazyRepository には、実際のリポジトリを作成するための高価なメンバー変数があります。各メソッドで、この変数が null かどうかを確認します。存在する場合は、実際のリポジトリを作成します。次に、各メソッドが実際のリポジトリに委譲されます。
于 2012-09-24T23:09:17.797 に答える
0

高価な依存関係のファクトリを注入するということは、その依存関係の消費者が、依存関係のインターフェースの高価な実装が 1 つあることを知っていることを意味します。消費者がそれに応じて実装を変更する場合、それは漏れやすい抽象化です。

このブログ投稿をご覧ください。Unity を使用してオンザフライでリポジトリのインターフェイスを実装する遅延プロキシを生成する方法を示します。

このスレッドによれば、 Castle Windsor も同じことができます。

于 2012-09-25T07:04:57.647 に答える