对象生命周期,Windows窗体和依赖注入(Windsor)

时间:2013-01-31 14:35:06

标签: c# winforms dependency-injection castle-windsor object-lifetime

快速背景:我已经(大部分)阅读了Mark Seemann的“.NET中的Depdendency Injection”,并准备成为DI忍者。我重构了我的代码库以使用构造函数注入,使用Windsor和SUCCESS连接我的对象!

......除了没有。我的程序最初在它的整个生命周期中显示了几种形式,这最初是通过new()根据需要完成它们来完成的。但是,既然我是NIT(忍者在训练中),我知道新的()是邪恶的,必须放逐到作文根。

问题:我的第一个端到端使用测试涉及向用户显示我的“主”窗口。可以关闭此窗口,以后可以再次启动新版本。这在后DI代码库中运行良好,直到第二次显示表单为止。崩溃。表格已经处理完毕。在连接我的DI容器时,我告诉它使用Form的类来实现一个特定的接口,并且应该期望它给该对象一个单一的生命周期。

问题:所以我很确定解决这个问题的方法是不依赖于表单实现的接口,而是依赖于该接口的工厂。这是我对如何继续的困惑。

我的第一个想法是创建一个与表单具有相同构造函数签名的工厂,存储所有这些依赖项,然后在需要时将new()向上移动一个表单。然而,这感觉就像穷人的DI,我已经经历了使用Windsor容器注册所有东西的麻烦。所以这导致我......

我的第二个想法是创建一个工厂,将DI容器作为依赖项,然后只需.Resolve()每次我需要的东西(这次使用瞬态生活方式)。我怀疑我会挂钩.Closed事件并在那里发布(遵循Register-Resolve-Release模式)。

真正的问题:我喜欢我的第二个想法,但出于某种原因,它感觉像是一个黑客。我不知道是不是因为它(并且有一种更好的方式)或者我的蜘蛛感觉还没有调整到DI。那么,底线,“第二个想法”是一种有效的方法还是代码味道?

另外,如果我将这种方法用于不能提供挂钩到“封闭”事件的方法,那么我应该如何设计释放机制,以便工厂提醒/鼓励我在完成时释放对象? (在某些时候我可能会忘记......)

谢谢!

1 个答案:

答案 0 :(得分:1)

最终为我工作的同时仍然保持我的下层不知道DI容器是在较低层创建工厂界面,但然后在我的组合根层实现该工厂。

即:

namespace MyApp.InterfaceLayer
{
    public interface IFormFactory
    {
        IForm GetForm();
    }
}
namespace MyApp.CompositionRoot
{
    class FormFactory : IFormFactory
    {
        Castle.Windsor.IWindsorContainer Container { get; set; }

        public FormFactory(Castle.Windsor.IWindsorContainer container)
        {
            Container = container;
        }
        public IForm GetForm()
        {
            return Container.Resolve<IForm>();
        }
    }
}

我当然会注册使用瞬态生活方式实现IForm的表单,并将我的容器注册为IWindsorContainer

到目前为止,这一直像冠军一样!