【问题标题】:DI and Singleton Pattern in one implementationDI 和单例模式在一个实现中
【发布时间】:2009-12-16 19:48:20
【问题描述】:

我想使用 Windsor IOC/DI 框架重构一些代码,但我的问题是我有一些单例类和工厂模式类,我不确定是否可以使用 DI 实现单例或工厂。

有没有人有任何想法,如果可能的话,怎么做?

【问题讨论】:

    标签: c# inversion-of-control


    【解决方案1】:

    Singleton 设计模式与 DI 不一致。虽然可以打开一个 Singleton 以至于 DI 和 Open/Closed Principle 开始变得有意义,但这将改变 Singleton 以至于它几乎不再是一个 Singleton。

    线程安全是您开始打开 ​​Singleton 时想到的一个大问题。

    最好简单地定义您的服务和类而不考虑它们的范围。如果您想在多个使用者之间共享一个对象,大多数 DI 容器都有 Singleton lifetime 的概念,它模仿了 Singleton 设计模式的优点而没有任何缺点。

    简而言之:单身人士是邪恶的,应该避免。

    另一方面,

    Abstract Factory 对于 DI 目的非常很有用。

    【讨论】:

    • 单身人士是我经常使用的东西,但读到这里,我似乎不得不改变我的策略了!我发现它们在某些情况下非常有用......但我可以看到你来自线程安全的地方。
    • 线程安全是一回事,但主要问题是违反了开放/封闭原则。
    • 如果我使用 DI 容器来管理单例的范围,为什么会违反 OCP?因为我不依赖静态方法来实现我仍然可以子类化它,所以我认为为单例使用 DI 容器可以让我保留 OCP。 ?
    • 如果您的 DI 容器实现了一个接口并且它恰好是一个单例,那么它不会违反 OCP - 它只是一个实现细节。危险在于,由于它是单例,随处可用,因此没有经验的开发人员可能会直接使用它,从而无意中造成紧密耦合。
    • 单例的常见用法(而不是将它们用于 Flyweights 等)和 DI 都解决了相同的问题 - 所需依赖项的位置。尝试将它们结合起来是没有意义的,因为您最终会两次解决相同的问题。只需使用 DI - 从长远来看,它会给您带来更大的灵活性。
    【解决方案2】:

    你没有,你让 IOC 容器来做。在显式调用工厂以获取对象的单例实例之前,现在您让 IOC 容器为您创建对象图,并将所有内容连接到它所属的位置。容器确保您的单例是单例,它充当工厂。

    如果您说的是让工厂在运行时决定提供哪种对象,则 DI 不适用于那里,除非您可以让 DI 容器将工厂注入您想要的位置并为您管理其范围。

    【讨论】:

    • IOC 框架是否也无法决定在运行时提供哪个对象?那么为什么在使用 DI 时以这种方式使用工厂呢?我会更多地使用工厂来创建相同或相似类的多个实例...
    • 我的意思是在使用 IOC 时,而不是“使用 DI”
    • 通常 IOC 框架是相当静态的,它们根据配置(xml、注释、属性文件等)为您创建对象,所以不,没有太多能力来决定动态创建什么。
    【解决方案3】:

    大多数现代依赖注入框架允许您指定它们是否应该在应用程序(或请求)的生命周期内提供单个对象实例,或者在您每次请求时创建新实例。

    您还可以在适当的时候使用 DI 框架来解决对工厂的依赖关系(如果这就是您的意思)。如果工厂根据运行时数据选择子类,或者依赖对象需要创建许多 IFoo 实例,您可能会这样做,在这种情况下,您可能会注入 IFooFactory

    【讨论】:

    • 我的意思是后者使用工厂创建某个类的许多实例,然后必须将工厂注入某个类。
    猜你喜欢
    • 2011-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-25
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    相关资源
    最近更新 更多