9

私は IoC コンテナーを使い始めたばかりなので、これがばかげた質問である場合は申し訳ありません。

アプリに次のようなコードがあります

internal static class StaticDataHandlerFactory
    {
        public static IStaticDataHandler CreateHandler(StaticDataUpdate staticDataUpdate)
        {
            if (staticDataUpdate.Item is StaticDataUpdateOffice)
            {
                return new OfficeUpdateHandler();
            }

            if (staticDataUpdate.Item is StaticDataUpdateEmployee)
            {
                return new EmployeeUpdateHandler();   
            }

            if (staticDataUpdate.Item == null)
            {
                throw new NotImplementedException(
                    string.Format("No static data provided"));
            }
            else
            {
                throw new NotImplementedException(
                    string.Format("Unimplemented static data type of {0}", staticDataUpdate.Item.GetType().FullName));
            }
        }
    }

これは基本的に、入力データを処理するための正しい戦略を返す単純なファクトリです。

IC コンテナーを使用すると、このようなコードを排除できますか? つまり、入力パラメーターのタイプに基づいて、ロードする具体的な実装を動的に選択できるようになりますか?

それとも私はここでコースから外れていますか?

4

5 に答える 5

9

実際には、コードの一部を制御システムの反転に置き換えることは可能ですが、それが良いアイデアかどうかはわかりません。依存性注入は、オブジェクトの動的な作成ではなく、システムの構成に最適な傾向があります。別の言い方をすれば、コンテナー自体は巨大なグローバル変数であり、そのためコードの多くに表示されるはずです。

余談ですが、このコードはデメテルの法則に違反しているようです。パラメータのタイプは「StaticDataUpdate」ではなく「StaticDataUpdateItem」にする必要があるようです。以上のことから、このコードを StaticDataUpdateItem のメソッド呼び出しとして書き直すことにはかなり強い議論があります。

私は IoC をかなり多用しましたが、動的なオブジェクトの作成は、抽象ファクトリ パターンを使用する方が適切です。つまり、アイテム自体にメソッドを追加してハンドルを生成するという考えが気に入らない場合は、コードをそのままにしておくのがおそらく最善です。

于 2008-11-13T09:54:17.133 に答える
3

あなたはコースからそれほど遠くはありません。私が理解しているように、あなたはかなり近いです。

私がこの種のものを最も一般的に構造化する方法は、依存性注入を使用して返されるUpdateHandlerを指定できるようにするだけで、FactoryクラスをIoCコンテナーに変換することです。したがって、StaticDataUpdateOfficeがOfficeUpdateHandlerを返すことを意味することを指定するロジックをコードに含める代わりに、StaticDataUpdateOfficeが(新しく指定された)m_officeUpdateHandler変数に含まれるものをすべて返すという単純なコードに変換できます。m_officeUpdateHandlerファクトリを呼び出す前に、Frameworkがの値を設定していることを確認している限り、問題はありません。m_officeUpdateHandlerまた、ニーズの変化に応じて、実行時にの値を任意の値に変更できます。

この依存性注入により、制御の反転プロセスを制御できます。ハンドラーを返す単純なファクトリを作成し、必要に応じて、どのハンドラーを別の場所に返すかを制御するロジックを抽象化できます。

注:この種のことに関する私の経験は、Springでの私の(非常に前向きな)経験によってかなり強く推進されているため、あなたの質問(および回答)の私の解釈に色を付ける可能性があります。

于 2008-11-11T23:17:36.187 に答える
1

ここでの他の回答に同意します。はい、そのようにすることができます。しかし、ジェネリックを使用しないのはなぜですか?

public static IStaticDataHandler CreateHandler<T>( params object[] args )
{...

ここで、args は ctor 引数として (たとえば、Activator に) 渡すことができます。

于 2008-11-12T17:26:35.787 に答える
1

短い答えはイエスです、それはそれを可能にします。このブログ投稿は、Windsor を使用して実行時に実装を選択する巧妙な方法を示しています。著者の Ayende は、ここここで詳しく説明しています。

私はまだこれを試していませんが、すぐに試してみます。

于 2008-11-11T22:57:53.793 に答える
-2

私はここで意味を成す言葉をまだ読んでいません。

IoC は構成のためのものですか?

動的なオブジェクトの作成は何が優れていますか? ジェネリック?これはすべてオフトピックです。

1) IoC は、「特殊化/継承よりも構成」の福音を実装するのに比べて、時間を大幅に節約できます。

したがって、IoC を使用するためのルール #1 は、「実装ではなくコントラクトにバインド」に従う長いコンストラクターを処理しなければならないことに本当にうんざりしている必要があるということです。

別の言い方をすれば、これは同じ理由 (カプセル化...) のためのテンプレート パターンの代替としての戦略パターンです...しかし、すべての追加のインターフェイス/抽象型を作成するのはより多くの作業であり、実行する作業はより多くなります。すべての IServiceProvicerThis および IResolverThat で毎回それを実行します...次のようなコード契約を退屈に履行しなければならないことにうんざりしていない場合:

IInterestingService 興味深い = ... インスタンスを取得しますが..

このようにさらに3行ほど追加してください..

それから

IAmazementService service = new AmazementService(興味深い、2 番目の戦略、3 番目の戦略など)

それは古くなります。したがって、堅実な設計を使用してコーディングできるほど賢い人なら誰でもよく知っているので、IC は決して問題ではありません。質問者はすべて間違った答えを持っています。

したがって、実際に上記を満たしている場合は、絶対に。IoC コンテナーは、処理を任せることで得られる「創造的な」作業をできるだけ多く実行するためにフックにかかっています。そして、明示的な new に対する最も一般的な創造の抽象化は、Mr. Factory です。

デイモン

于 2009-10-11T19:26:51.617 に答える