私は同僚のためにシングルトンを介した依存性注入の使用について聞いていました。それが互いに置き換えることができる2つの直交パターンであるかどうかまだわかりませんか?または、DIはシングルトンパターンをテスト可能にする方法ですか?
次のコードスニペットをご覧ください。
IMathFace obj = Singleton.Instance;
SingletonConsumer singConsumer = new SingletonConsumer(obj);
singConsumer.ConsumerAdd(10,20);
SingletonConsumer
は、タイプIMathFace
のパラメーターを受け入れます。シングルトンクラスに内部的にアクセスする代わりに、SingletonConsumer
は呼び出し元から渡されたシングルトンインスタンスを取得します。これは、依存性注入を介してシングルトンクラスを使用する良い例ですか?
静的なアクセサーで従来のシングルトン実装を使用する代わりに、依存性注入を使用してサービスの単一インスタンスを注入する必要があると彼は言っていたと思いますMySingleton.Instance
。
public class MySingleton
{
public static MySingleton Instance{get{...}};
}
古典的なシングルトン実装では、すべてのコードはそのサービスがシングルトンであることに依存しています。基本的には、MySingleton.Instance
。
一方、DIを使用すると、コンストラクターに渡されたサービスのインスタンスを取得して格納します。このサービスのインスタンスが1つしかないことは、実装の詳細です。簡単に変更して、使用するコードに別のインスタンスを与えることができます。そうすれば、インスタンスが1つしかないことを強制するのではなく、たまたま単一のインスタンスによって実装されるクラス/インターフェースがいくつかあります。
これは、たとえばテストのためにサービスのモック実装をしたい場合、またはプログラムの異なる部分がそのサービスの異なる構成を必要とする場合に役立ちます。
はい、そうです。シングルトン経由でオブジェクトにアクセスする代わりに、オブジェクトへの参照を渡しているため、コンストラクターインジェクションを使用しています。
他の人が指摘していることは、これらの概念は関連していないということです。注入先のオブジェクトは、注入されたオブジェクトがどこから来たのか本当に気にしないので、シングルトンインスタンスの使用は特別なことではありません。
シングルトンパターンとDI/IoCが交差するケースが1つあります。シングルトンの注入です。
ほとんどのDIフレームワークは、注入されたオブジェクトの単一のインスタンスをインスタンス化するように構成できます。そのようなオブジェクトのインスタンスを要求するすべてのコンシューマオブジェクトは、同じ単一のインスタンスを取得します。そのインスタンスは、定義上、シングルトンです。コンセプトの重複については以上です。
ここでの混乱は、シングルトンとシングルトンインスタンスへの静的アクセサー/ゲートウェイという2つの概念が融合していることです。
あなたが正しく特定したように、あなたの同僚は、_Singleton.Instance
_(静的ゲートウェイ)を使用して直接アクセスするのではなく、依存関係を注入することを提案しています。
これがシングルトンパターンと実際には何の関係もない理由は、同じDIの概念がnew Foo()
を使用して非シングルトンオブジェクトをインスタンス化する場合にも等しく当てはまるためです。依存関係は、それがシングルトン実装であるかどうかに関係なく注入されます。