Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RegisterInstanceで登録したインスタンスの生存期間を設定したい #169

Closed
sakano opened this issue Mar 28, 2021 · 6 comments

Comments

@sakano
Copy link
Contributor

sakano commented Mar 28, 2021

ver1.6.0現在、RegsiterInstanceで登録したインスタンスは全てLifetime.Scopedで管理されているようです。
それによってIDisposableを実装したインスタンスがLifetimeScopeごとにDisposeされてしまっています。

LifetimeScopeに親子関係を持たせる場合、子のLifetimeScopeが破棄されると親のLifetimeScopeでも登録したインスタンスがDisposeされた状態になるので困ってしまいます。

RegisterInstanceのタイミングでLifetimeも指定できるAPIがあると嬉しいです。

@hadashiA
Copy link
Owner

LifetimeScopeに親子関係を持たせる場合、子のLifetimeScopeが破棄されると親のLifetimeScopeでも登録したインスタンスがDisposeされた状態になる

お。どちらかというと この挙動が おかしいですね。。
子のDisposeが親のインスタンスに影響しないように修正されれば問題ないでしょうか ?

RegisterInstanceのタイミングでLifetimeも指定できるAPI

個人的には、生成済みのインスタンスが使用される場合は、生成タイミングと寿命を変更のしようがないので、ライフタイムの指定はナンセンスかなと思っています。

@sakano
Copy link
Contributor Author

sakano commented Mar 29, 2021

外で作ったインスタンスをLifetimeScopeに管理してほしくないのでLifetime.TransientにしてDisposeされないようにしたい、などと考えていました。
そもそもIDisposableでない形で渡せば回避できるのでLifetime.Singleton固定でも大丈夫です。

@sakano
Copy link
Contributor Author

sakano commented Mar 29, 2021

Lifetime.Singleton固定でも大丈夫、と書きましたがもう少し考えてみました。

#171 のプルリクだとResolveされた場合にのみDisposeされることになりそうです。
RegisterInstanceした段階ではDisposeが呼ばれるか不定なのでかなり使いづらいことになります。

登録されたインスタンスをDIコンテナが破棄すべきかはAutofacでも議論になっていました。
autofac/Autofac#780
結論としてはデフォルトで破棄して、破棄させたくない場合は明示的にExternallyOwned()を付けるようです。

Resolveされるかに関わらず必ず破棄されるように直すのは面倒な気もするので、VContainerでは破棄しないとするのもいいのではいでしょうか。
autofacの議論でも破棄しない方がよさそう、と言いながら現状の形になったのは互換性のためではないかと思います。はっきり書かれていないので推測になりますが。
私としても破棄する責任を持つのはインスタンスを生成した側、とするのが自然だと感じます。

@hadashiA
Copy link
Owner

hadashiA commented Apr 5, 2021

RegisterInstanceした段階ではDisposeが呼ばれるか不定なのでかなり使いづらいことになります。

これはたしかにそうですね。
Resolveの有無に関わらず同じ挙動をしないとわかりずらいですね。

僕としては、どこからも Resolve されないのに RegisterInstance されている状態がそもそもあまり望ましくないと思っていたりしますが、とはいえ 挙動は統一されて良いとは思います。

結論としてはデフォルトで破棄して、破棄させたくない場合は明示的にExternallyOwned()を付けるようです。

自分は どちらかというとこの挙動(デフォルトでコンテナが破棄)のほうがしっくりきていたりします。

RegisterInstance したものをコンテナに破棄してほしいかどうかは、場合によるのではないでしょうか。

  • 自力で どこかでDispose を呼ぶ必要がある場合には、コンテナに管理を委譲できるほうが自然な気がしてます
  • コンテナ経由 で 使用できるインスタンスが、外でDisposeされているかもしれない (コンテナより寿命が短いかもしれない)というのは微妙に予想外な気がします

ただ 、どちらをデフォルトにするかはともかく、双方の機能を選択できるのがよさそうです。
autofac の issueも参考になります。ありがとうございます

@hadashiA
Copy link
Owner

hadashiA commented May 3, 2021

RegisterInstance の挙動を検討しましたが、少し考えが変わりました。やはり提案してもらった案を採用しようと思います。

変更:

  • RegisterInstance で登録したインスタンスはコンテナで管理しない
    • 自動的なDispose は実行されない
    • また、メソッドインジェクションも実行されない

理由:

--

I considered the behavior of RegisterInstance, but changed my mind a bit. I think I'll still adopt the idea you suggested.

Change :

  • Instances registered with RegisterInstance are not managed by the container.
    • Automatic Dispose will not be performed.
    • Also, method injection will not be performed.

Reason:

@hadashiA
Copy link
Owner

hadashiA commented May 8, 2021

Released in v1.8.0

参考になりました。また何かあればお願いします。

@hadashiA hadashiA closed this as completed May 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants