依存性注入とシングルトン。それらはまったく異なる2つの概念ですか?


17

私は同僚のためにシングルトンを介した依存性注入の使用について聞いてきました。互いに置き換えることができる2つの直交パターンであるかどうかはまだわかりませんか?または、DIはシングルトンパターンをテスト可能にする方法ですか?

次のコードスニペットをご覧ください。

    IMathFace obj = Singleton.Instance;

    SingletonConsumer singConsumer = new SingletonConsumer(obj);

    singConsumer.ConsumerAdd(10,20);

SingletonConsumer型のパラメータを受け入れていますIMathFace。内部的にシングルトンクラスにアクセスする代わりにSingletonConsumer、呼び出し元から渡されたシングルトンインスタンスを取得します。これは、依存性注入を介してシングルトンクラスを使用する良い例ですか?


DIがシングルトンを置き換える方法を教えてください。

7
シングルトンはデザインパターンです。DI / IoCはテクニックです。
デイブ

2
DIは、バナナがキャブレターを置き換えることができる以上、シングルトンを置き換えることはできません。それらはまったく異なる概念です。
デイブ

私の例は有効です。

1
はい、それは見(非シングルトンについても同様である)カプセル化の犠牲の上に来るかもしれない:stackoverflow.com/questions/1005473/...

回答:


17

彼は、静的アクセサを備えた従来のシングルトン実装を使用する代わりに、依存性注入を使用してサービスの単一インスタンスを注入する必要があると考えていたと思いますMySingleton.Instance

public class MySingleton
{
    public static MySingleton Instance{get{...}};
}

古典的なシングルトン実装では、すべてのコードはそのサービスがシングルトンであることに依存しています。あなたは基本的にあなたが使うときはいつもその仮定を消費コードにハードコードしますMySingleton.Instance

一方、DIでは、コンストラクターに渡されたサービスのインスタンスを取得して保存します。このサービスのインスタンスが1つしかないことは、実装の詳細です。簡単に変更して、消費するコードに別のインスタンスを与えることができます。そうすれば、インスタンスが1つしかないことを強制する代わりに、たまたま単一のインスタンスによって実装されるクラス/インターフェースがあります。

これは、たとえば、テストのためにサービスの模擬実装が必要な場合、またはプログラムのさまざまな部分がそのサービスのさまざまな構成を必要とする場合に役立ちます。


4

はい、あなたは正しいです。シングルトンを介してオブジェクトにアクセスする代わりに、オブジェクトへの参照を渡しているため、コンストラクター注入を使用しています。

他の人が指摘しているのは、これらの概念は関連していないということです。シングルトンインスタンスを消費することは特別なことではありません。なぜなら、インジェクトするオブジェクトは、インジェクトされたオブジェクトがどこから来たのかを本当に気にしないからです。


2

シングルトンパターンとDI / IoCが交差する場合が1つあります。シングルトンの注入です。

ほとんどのDIフレームワークは、挿入されたオブジェクトの単一インスタンスをインスタンス化するように構成できます。そのようなオブジェクトのインスタンスを要求するすべてのコンシューマオブジェクトは、同じ単一のインスタンスを取得します。そのインスタンスは、定義によりシングルトンです。コンセプトの重複についてはこれで終わりです。


1

ここでの混乱は、シングルトンとシングルトンインスタンスへの静的アクセサ/ゲートウェイという2つの概念が混同されていることです。

正しく特定したように、同僚はSingleton.Instance(静的ゲートウェイ)を使用して直接アクセスするのではなく、依存関係を注入することを提案しています。

これが実際にシングルトンパターンとは関係ない理由は、同じDIの概念がでシングルトンでないオブジェクトのインスタンス化にも等しく適用されるためnew Foo()です。依存関係は、シングルトン実装であるかどうかに関係なく注入されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.