1

このメソッドを使用して、RegisterInitializer次のように基本タイプにプロパティを挿入します。

container.RegisterInitializer<BaseHandler>(handler =>
{
    handler.Context = container.GetInstance<HandlerContext>();
});

これはうまく機能しますがRegisterInitializer、BaseHandlerから継承するすべての登録済みタイプで起動されるわけではありません。私が自分自身を呼んだとき、それは実行されていないようですnew

var url = ConfigurationManager.AppSettings["NotificationServiceUrl"];
container.Register<Handler<NotifyCustomerMessage>>(() => 
    new NotifyCustomerHandler(url));

// many other Handler<T> lines here

それはなぜですか、そしてどうすればこれを解決できますか?

4

1 に答える 1

2

アップデート

この動作はSimpleInjector2で変更されました:InitializersはFunc<T>登録時にも起動するようになりました。その理由は、Simple Injectorが明示的なライフスタイルをサポートし、実際にはStructureMapのように動作するためです(以下で説明します)。


あなたの観察は正しいです。Simple Injectorのドキュメントでは、次のように説明しています。

new注:コンテナーは、演算子を使用して手動で作成されたタイプの初期化子デリゲートを呼び出すことはできません。可能な限り、自動コンストラクタインジェクションを使用してください。

この問題を克服する最良の方法は、SimpleInjectorが自動コンストラクターインジェクションを使用できるようにすることです。

コンストラクター引数NotifyCustomerHandlerを取りstringます。これにより、コンストラクターの自動注入を実行できなくなります。あなたNotifyCustomerHandlerには複数の責任があるようです。このサービスをインターフェースの背後に隠しINotificationService、ハンドラーがそのインターフェースに依存するようにすることで、ハンドラー機能から通知サービスを抽象化します。その構成値を通知サービスに注入することができます。

SimpleInjectorがこのように動作する理由に関する背景情報

他のDIフレームワーク(StructureMapとそのOnCreationForAllメソッドなど)は、型を新しくした場合でもデリゲートを呼び出しますが、SimpleInjectorは呼び出しません。これは、フレームワークがユーザーにライフスタイルの登録を期待する違いが原因です。

StructureMapでは、メソッドを明示的に呼び出すことでライフスタイルを構成しますLifecycleIs。Simple Injectorを使用すると、ユーザーはライフスタイルを自分で実装するデリゲートを登録することでライフスタイルを構成することが期待されます。たとえば、ドキュメントのスレッドごとのライフスタイルの例を見てください。StructureMapでは、ライフタイムを制御するフレームワークですが、Simple Injectorでは、多くの場合、ユーザー次第です。

つまり、StructureMapは、登録されたデリゲートが常に新しいインスタンスを作成することを期待していますが、SimpleInjectorにはこの期待がありません。StructureMapは新しいインスタンスが返されることを期待しているため、デリゲートを呼び出した後、そのオブジェクトを安全に初期化できます。インスタンスのキャッシュは他の場所で行われます。ただし、Simple Injectorは、そのようなデリゲートから返されたオブジェクトに対して初期化子を呼び出しません。これは、同じオブジェクトを何度も再初期化する可能性があり、予期しないアプリケーションの動作やパフォーマンスの問題を引き起こす可能性があるためです。

これがお役に立てば幸いです。

于 2011-06-24T08:24:02.740 に答える