0

StructureMap を使用してリポジトリをコントローラー コンストラクターに挿入する標準 IoC セットアップの MVC プロジェクトがあります。

また、さまざまなコントローラーから呼び出すことができる共通のメソッドを持つことができる静的な「ユーティリティ」クラスが必要であると判断しました。たとえば、私は持っています:

public static IEnumerable<CountryCode> GetCountryList()
{
    ICountryCodeRepository repo = ObjectFactory.GetInstance<ICountryCodeRepository>();
    IEnumerable<CountryCode> countries = repo.GetAll();
    return countries;
}

ご覧のとおり、これは ObjectFactory からリポジトリ オブジェクトを直接作成します。問題は、コントローラーを単体テストしたいときに、コントローラーのリポジトリをモックできるが、ユーティリティ クラス (コントローラーが最終的に呼び出す) のリポジトリをモックできないことです。他の理由があると確信しています。私のユーティリティ クラスは間違っていますが、これは私が今のところ見ているものです。また、私が持っているのはデザインが悪いと言っているものも読んだことがありますが、それを修正する方法がわかりません。

GetCountryList() 関数でレポ オブジェクトを受け入れることを考えていました

GetCountryList(ICountryCodeRepository _repo)

呼び出し元のコントローラーはそれを渡しますが、すべてのコントローラーがユーティリティ関数に必要なものを知る必要があるため、別の依存関係の問題が発生するだけではありませんか?

それとも、これらのユーティリティ メソッドを挿入するために何らかの方法で StructureMap を使用することは可能ですか?

4

1 に答える 1

2

自分がやっていることは悪いデザインだとわかっていても、少なくとも問題はありません。それは問題ありません。この投稿を読んでいる人もそれを知っており、あなたと同じ過ちを犯さないようにします.

しかし、要点を言えば、静的クラスでプロバイダーを使用できます。

public static class Foo
{
    public static Func<ICountryCodeRepository> CountryRepoProvider = 
        () => ObjectFactory.GetInstance<ICountryCodeRepository>();

    public static IEnumerable<CountryCode> GetCountryList()
    {
        return CountryRepoProvider().GetAll();
    }
}

そして今、単体テストでそれをモックできます:

Foo.CountryRepoProvider = () => mocha; 

または、ASP.NET MVC 3 を使用していて、DI フレームワークが依存関係リゾルバーを使用している場合、少なくとも DI フレームワークに依存しないようにすることで、このコードを改善できます。

public static IEnumerable<CountryCode> GetCountryList()
{
    var repo = DependencyResolver.Current.GetService<ICountryCodeRepository>();
    return repo.GetAll();
}

単体テストでは、もちろん、サービスのモック インスタンスを吐き出すカスタムの依存関係リゾルバーを作成できます。

そして今、このコードを見ると、本当に自分自身にこう思うかもしれません:私は何をしているの? DIからフェッチしているリポジトリに委任する1つのライナーメソッドを使用して静的クラスを作成しています。DI フレームワークを利用して、このリポジトリのインスタンスを必要な場所に直接注入し、必要なメソッドを呼び出すだけで、何のメリットがあるでしょうか? これらのワンライナー静的メソッドで単体テストを行っているのは何ですか? なぜ私は時間を無駄にしているのでしょうか

もちろん、より複雑なロジックを処理する必要がある場合は、必要なリポジトリをコンストラクターの依存関係として取得し、それらに対して複雑なビジネス操作を実行するサービス層を単純に記述します。次に、DI フレームワークを構成して、すぐに使用できるサービスのインスタンスをコントローラーまたは必要な場所に挿入します。見る?静的クラスは必要ありません。弱い結合と単体テストに適したコード。

于 2012-06-28T16:38:54.920 に答える