3

我和一位开发人员正在就对象属性的延迟加载进行交谈(轻描淡写)。

  • 他说使用静态 IoC 查找调用来解析和延迟加载对象的对象。
  • 我说这违反了 SRP,并使用拥有的服务来解决该对象。

那么,您将如何处理 IoC 和 SRP 之后的延迟加载?

您不能对延迟加载的属性进行单元测试。他反驳了这一说法,“你已经对 UserStatsService 进行了单元测试——你的代码覆盖了。” 一个有效的观点,但该属性仍未经过“完整”覆盖的测试。

设置/代码模式:

  • 项目正在使用严格的依赖注入规则(注入到所有服务、存储库等的 ctors 中)。
  • 项目通过 Castle 使用 IoC(但可以是任何东西,比如 Unity)。

下面是一个例子。

public class User
{
  public Guid UserId { get; set; }

  private UserStats _userStats;
  // lazy-loading of an object on an object
  public UserStats UserStats
  {
    get
    {
      if (_userStats == null)
      {
        // ComponentsLookup is just a wrapper around IoC 
        // Castle/Unity/etc.
        _userStats = 
          ComponentsLookup
            .Fetch<UserStatsService>()
              .GetByUserId(this.UserId);
      }
      return _userStats;
    }
  }
}

上面显示了延迟加载对象的示例。我说不要使用它,并在需要该对象的任何地方从 UI 层访问 UserStatsService。

编辑:下面的一个答案让我想起了 NHibernate 延迟加载的技巧,即虚拟化您的属性,允许 NHibernate 创建延迟加载本身的过载。Slick,是的,但我们没有使用 NHibernate。

没有人真正解决延迟加载的问题。一些好的文章和 SO 问题接近了:

我确实看到了延迟加载的好处。不要误会,我所做的只是延迟加载我的复杂类型及其子类型,直到我切换到忍者的 DI 方式。好处在于 UI 层,其中显示了用户的统计信息,例如,在 100 行的列表中。但是对于 DI,现在您必须引用几行代码来获取该用户统计信息(不违反 SRP 并且不违反 Demeter 定律),并且它必须走这条长长的查找路径 100 多次。

是的,添加缓存并确保将 UserStatsService 编码为用作单例模式会大大降低性能成本。

但我想知道是否还有其他人有一个 [固执的] 开发人员,他们不会完全遵守 IoC 和 DI 规则,并且有有效的性能/编码点来证明变通方法的合理性。

4

1 回答 1

5

实体本身不应该负责延迟加载。这是一个基础设施问题,其解决方案将在别处。

假设一个实体在两个不同的上下文中使用。首先,它的孩子被大量使用并且急切地加载。其次,它们很少使用并且是延迟加载的。这也是该实体的担忧吗?配置会是什么样子?

NHibernate 通过代理实体类型来回答这些问题。基础设施将类型属性IList<Entity>设置为了​​解延迟加载的实现。该实体仍然幸福地不知道。还处理了父引用(如您的问题),只需要一个简单的属性。

现在关注点在实体之外,基础设施 (ORM) 负责确定上下文和配置(如急切/延迟加载)。

于 2010-01-12T00:55:55.473 回答