快速背景:我已经(大部分)读完了 Mark Seemann 的“.NET 中的依赖注入”,并准备成为一名 DI 忍者。我重构了我的代码库以使用构造函数注入,使用 Windsor 连接我的对象,并且成功了!
……除了没有。我的程序最初在其整个生命周期中显示了几种形式,这最初是通过根据需要将它们全部 new() 来完成的。但是,既然我是 NIT(忍者培训),我知道 new() 是邪恶的,必须将其放逐到组合根中。
问题:我的第一个端到端使用测试涉及向用户显示我的“主”窗口。可以关闭此窗口,稍后可以再次调出新版本。这在后 DI 代码库中运行良好,直到第二次显示表单。碰撞。表格已经被处理掉了。在连接我的 DI 容器时,我告诉它使用 Form 的类来实现特定的接口,并且正如预期的那样,它为该对象提供了单例生命周期。
问题:所以我很确定解决这个问题的方法是不依赖于表单实现的接口,而是依赖于该接口的工厂。这是我对如何进行感到困惑的地方。
我的第一个想法是创建一个与表单具有相同构造函数签名的工厂,存储所有这些依赖项,然后在需要时创建一个表单。然而,这感觉就像穷人的 DI,我已经经历了在 Windsor 容器中注册所有东西的麻烦。所以这导致我...
我的第二个想法是创建一个工厂,将 DI 容器作为依赖项,然后每次只需要 .Resolve()s (这次使用短暂的生活方式)。我怀疑我会加入 .Closed 事件并在那里释放(遵循 Register-Resolve-Release 模式)。
真正的问题:我喜欢我的第二个想法,但出于某种原因,它感觉就像一个黑客。我不知道这是因为它是(并且有更好的方法)还是我的蜘蛛侠感官还没有针对 DI 进行调整。那么,归根结底,“第二个想法”是一种有效的方法还是一种代码味道?
另外,如果我将这种方法用于不提供挂钩“关闭”事件的方法,那么我应该如何设计释放机制,以便工厂提醒/鼓励我在完成后释放对象?(在某些时候我可能会忘记,否则......)
谢谢!