制御の逆転とIDisposable (DIxAOPによる解決)
んなわけでAOPでIDisposableをインターセプトして、IDisposable.Disposeを無視(artonさんの言ってる事) or コンテナ制御への無効な介入として拒絶して例外を投げる。(自分が言ったパターン)
AOPコンテナによるオブジェクトライフサイクルの管理 - 菊池 Blog
なるほど納得。やはり、私が「Interface Injection」という言葉に対して勝手に混乱していただけだった。
あんまり実装方法は考えていませんけど、AOPできてるのであれば多分できると思います。
noopにしてしまうのであれば、例えばSeasar2の世界であれば、以下のような何もしないインターセプタ実装である"NoopInterceptor"を用意しておき、
public class NoopInterceptor : AbstractInterceptor { public override object Invoke(IMethodInvocation invocation) { return null; } }
あとは、DIコンテナ側で"singleton"かつ"IDisposable"なオブジェクトに対して、Disposeメソッドにポイントカットを適用してインターセプタをこっそり設定するか、自動生成対象であれば、予め対象のクラスの定義に、以下のようにAspectアノテーションを設定してやれば
[Component(Instance = InstanceType.SINGLETON)] [Aspect(Pointcut = "Dispose", Value = "NoopInterceptor")] public class SingletonAndDisposable : IDisposable { 〜 }
これで、他のインタフェースやコードを書かなくてもDisposeは無効にできる。noopではなく代わりに例外を投げたければ、また別のインターセプタ実装を用意してやれば良いだけだ。
当然だが、前回のエントリに比べて「縛り」が少ない分、今回の方法の方が私は好みである。
追記 : このままではちょっとしたまずいことが発生する。それに関してはまた別なエントリで。