.NETにはSimpleInjectorという非常に軽量でよくできたDIコンテナがあります。
私はこれを多用しているのですが、その際にインスタンスを1度生成したつもりが複数生成される事象に、悩まされることがありました。システムで一つしか生成しないインスタンスで、そのインスタンス生成時にやや重たい処理をしたかったのですが、実際には2回実行されていました。
SimpleInjectorは次のように利用します。
var container = new Container();
container.Register<Foo>();
container.Register<Bar>();
container.Verify();
var foo = container.GetInstance<Foo>();
SimpleInjectorでは依存性を登録した後、Verifyで登録が不足しているオブジェクトがないかベリファイすることができますが、実はこの時内部でインスタンスが生成されているために、前述のようなインスタンスの複数生成が行われます。
ではVerifyを外せばいいかというと、つぎの二つの問題があります。
- 開発時はVerifyしておかないと、不具合の発見が遅れる
- Verifyを明示的に呼ばなくても、GetInstanceした際に、Verifyしていなければ自動的に実行される
そのため、つぎのように実装するとよいのではないかと思います。
var container = new Container();
container.Register<Foo>();
container.Register<Bar>();
# if DEBUG
container.Verify();
# else
container.Options.EnableAutoVerification = false;
# endif
var foo = container.GetInstance<Foo>();
Debug実行時は明示的にVerifyを呼び出し、そうではない場合は、AutoVerificationを明示的にOFFにします。
これでReleaseビルドされたモジュールでは不要なインスタンス生成が避けられるはずです。
なおコメントでいただきましたが、登録するインスタンスをSingletonとして登録できる場合は、そちらでも回避は可能だと思います。どちらが向いているか、ケースによって検討してみてください。