2012-02-18 8 views
17

私が理解する限り、SimpleIocはGetInstanceメソッドを使用して、登録されているクラスのインスタンスを取得します。インスタンスが存在しない場合、インスタンスが作成されます。ただし、このインスタンスはキャッシュされ、常に取得されます。これはシングルトンパターンを模倣します。SimpleIoc - 必要なたびに新しいインスタンスを提供できますか?

私は、このViewModelが2回必要となる可能性が低い場合、ViewModelのインスタンスをメモリに保持する必要はないと考えています。そのため、必要なたびに新しいインスタンスを作成したいと思います。私たちはのviewmodelsのための工場を持っているしている場合は、我々はこのような性質を持っています:

public MyViewMOdel MyViewModel 
{ 
    get { return SimpleIoc.Default.GetInstance<MyViewModel>(); } 
} 

この1つは、私はすべてのケースではベストプラクティスではありませんだと思うシングルトンパターンを使用しています。この問題を回避するために、私はこれを行う:

public MyViewModel MyViewModel 
{ 
    get { return new MyViewModel(SimpleIoc.Default.GetInstance<ISomeInterface>()); } 
} 

この1つは私が今までMyViewModelのコンストラクタを変更した場合、私はまた、このプロパティを更新する必要がありますという欠点があります。大したことではありませんが、依然として何らかの依存関係があります。

このシナリオをどのように扱いますか、私には何かがありますか?非共有インスタンスが返されないようにした理由について説明します。

もう1つの質問は、MVVMディープダイブセッションLaurentは、特定のViewModelを登録した直後にGetInstanceメソッドを使用して、コンテナにこのViewModelのインスタンスが既に存在することを確認します。なぜこれが必要なのですか? ViewModelLocatorからViewModelをフェッチしている場合は、必要に応じて作成します。それではなぜ私はそれらを前もって作成させたいのですか?

答えて

9

GetInstanceメソッドに別のキーを渡すことで、毎回異なるインスタンスを取得できます。ただし、インスタンスはキャッシュされるため、キャッシュに保持しない場合は、対応するキーを使用して登録解除を呼び出す必要があります。

デモでは、MainVMがSecondaryVMにメッセージを送信していたため、VMを前もって作成していました。 Messengerへの登録はSecondaryVmのコンストラクタで行われるため、メッセージの受信を開始する前に作成する必要があります。メッセンジャーは非常にデカップリングされているのですばらしいですが、デカップリングを補うために余分な作業をする必要があるケースの1つです。SecondaryVMは、MainVMがメッセージを参照しなくてもメッセージのターゲットです。

希望します。あなたが言いたい場所を新しいインスタンスに特定のタイプが要求されており、この機能を見つけるが実装されていない各時間を提供するSimpleIoCと格闘した後 乾杯、 ローラン

+0

こんにちは、Laurent、共有されていないインスタンスの場合は、キーを使用しているかどうかは関係ありません(同じビューの複数のインスタンスが同時に存在しないと仮定します)。どちらの場合も、私はビューモデルを登録/登録解除する必要があるので、それらについて追跡する必要があります。 共有インスタンスと非共有インスタンスのための登録オプションがあったとしても、それはまだ単純なIocになると思います。私はそれがちょうどコンテナに作成されたインスタンスを追加する必要はないと思いますか? – Goran

+2

あなたのソリューションは、コンストラクタインジェクションが使用されていない場合にのみ機能します(これは良いことではありません)。コンテナが依存関係を挿入する責任がある場合、新しいインスタンスを作成してコンストラクタに挿入する方法はありません。 私のコードでSimpleIoC.GetInstance()を呼び出すことを避けようとしていますが、コンテナによっては悪い習慣です。 SimpleIoCに、新しいインスタンスを常に作成して、1つのインスタンスをキャッシュする代わりに挿入するようにするにはどうすればよいですか? SimpleIoC.Registerのシンプルな "キャッシュ"フラグで十分です。 – TheAgent

2

SimpleIOCは簡単なIOCコンテナです。いくつかの短所があるでしょう...しかし、あなたはそれに拘束されず、いつも別のICOコンテナ(例えばUnity、Autofac、Castle、...)を使うことができます。

Laurent statesとして、彼はSimpleIOCをthis containerにモデル化しました。彼はまた、彼のインスピレーションの源としてthis containerを述べている。

ただし、は、MVVMでセカンダリコンテナを使用することはできません。私のプロジェクトのいくつかでは、Unityを使用しましたが、他のすべてのIOCコンテナも同様にうまくいくでしょう。それは要件の問題であり、顧客の好みです。

+1

こんにちは、私は別のコンテナを使用することができますが、MVVMライトを使用しているので、ユニティ(または他のIoC)の高度な機能を必要としない場合は、オファー。ここで私が考えているのは、これは高度な機能ではなく、それを実装するにはあまりにも多くのコーディングを必要とせず、頻繁に使用される機能だということです。 SimpleIocを使用する他のプログラマーが、ビューモデルの非共有インスタンスの要件をどのように処理しているかを調べることにも興味がありました。 – Goran

0

(上記受け入れられたキーベースの方法は、シナリオに合いませんデータベース操作を実行し、毎回接続をスローする)、IoCとFactoryパターンを組み合わせた比較的適切なソリューションを考え出しました。 特定のタイプの新しいインスタンスを関数によってインスタンス化するクラスを作成します。

class MyObjectFactory: IMyObjectFactory 
{ 
    public MyObject CreateObject() 
    { 
     return new MyObject(); 
    } 
} 

MyObjectファクトリクラスのインターフェイスを作成します。

public interface IMyObjectFactory 
{ 
    MyObject CreateObject(); 
} 

その後工場MyObjectにのインスタンスを使用するすべてのクラスにを提供するために、IoCコンテナを設定します。

SimpleIoc.Default.Register<IMyObjectFactory, MyObjectFactory>(); 

代わりに(そのMyObjectFactory要件を宣言しMyObjectにの新しいインスタンスを必要とするすべてのクラスMyObjectの要件の)コンストラクタインジェクタのコンストラクタで:

public class MyObjectUser 
{ 
    MyObject _myObject; 
    public MyObjectUser(IMyObjectFactory factory) 
    { 
     _myObject = factory.CreateObject(); 
    } 
} 

この方法で私はあなたがボウではないと思うFactoryパターンの限界によって制限され、IoCコンテナとコンストラクタインジェクションの利点をすべて持ち、SimpleIoCの制限を回避します。

関連する問題