1

我们创建了一个单例对象(SsoSettingsProvider),我们在其中注入具有生活方式 PerWebRequest 的对象(IReservationService 在我们的示例中是 WCF 客户端)。在构造函数中,我们使用这个对象来获取一些数据,并将这些数据放在一个私有字段中。

public class SsoSettingsProvider : ISsoSettingsProvider
    {
        readonly LogonSettings _logonSettings;


        public SsoSettingsProvider(IReservationService reservationService)
        {
           _logonSettings = reservationService.GetSSOSettings();
        }        
    }

如果我们看看温莎城堡可能的生活方式不匹配,它会说:

“具有生活方式 Singleton 的组件 'SsoSettingsProvider / ISsoSettingsProvider' 依赖于具有生活方式 PerWebRequest 的'后期绑定 IReservationService' 这种依赖关系通常是不希望的,并且可能导致各种错误。”

该信息说只有可能性,但在这种情况下,我认为这不是问题,因为注入的对象没有在字段中引用,因此可以进行垃圾收集。我对吗 ?

4

1 回答 1

1

在这种情况下,我认为这不是问题,因为注入的对象没有在字段中引用,因此可以进行垃圾收集。我对吗?

Castle Windsor 对Captive Dependencies发出警告。主要问题不是实例没有被垃圾收集,而是一个类将重用一个不打算重用的实例。

简单的示例是当您将 aDbContext注入配置为单例的类中时。尽管这将导致在DbContext其单例使用者超出范围(通常是应用程序结束时)之前保持活动状态。DbContext但是,不应在多个请求上重用A。一方面,因为它根本不是线程安全的。最重要的是,它很快就会过时,这会导致它返回缓存的数据,而不是重新查询数据库。

出于这个原因,我们通常将 DbContext 注册为 Scoped。然而,这确实意味着它的所有消费者最多应该和 , 一样长DbContext,以防止它破坏应用程序。这就是Castle所警告的。

但是,在您的情况下,您不会将 存储IReservationServiceSsoSettingsProvider. 这仍然是一个问题,因为可以合理地预期IReservationService返回的对象不会超过IReservationService(否则IReservationService将被注册为 Singleton)。既然从 的 角度 来看SsoSettingsProvider, 无法 知道 存放 是否 安全LogonSettings, 最好根本 不 存放.

最重要的是,正如这里所说,注入构造函数根本不应该使用它们的依赖项。这会导致对象组合缓慢且不可靠。

因此,即使您可能已经分析了您的设计并确定这适用于您的特定情况,我还是建议您执行以下操作之一:

  • 存储IReservationService为私有字段,仅在SsoSettingsProvider调用 其中一个成员时调用并防止存储。这会迫使您制作作用域或单例。能不能单例,只能自己去查了。GetSSOSettingsSsoSettingsProviderLogonSettingsSsoSettingsProviderIReservationServiceIReservationService
  • 如果SsoSettingsProvider只对 感兴趣LogonSettings,并且LogonSettings是一个在应用程序启动后不会改变的常量值,则应LogonSettings直接注入SsoSettingsProvider的构造函数。这简化SsoSettingsProvider了加载并将其推LogonSettings送到合成根。
于 2017-09-01T12:38:03.177 回答