如果这个问题已经得到解答,我深表歉意,但我找不到任何答案。
在最近的一个面试问题中,我被问及如何实现延迟加载。场景如下:
解决方法:
- 网站项目
- 默认.aspx
- 对象收集项目
- 订单
- 订单项
- 服务层
- 订单服务
- 存储库层
- 订单库
Order 对象将有一个 IList。订单存储库将有一个返回所有订单的方法(为了更快,它不会返回每个订单的所有行项目,因此它为空)。
问题是“我将如何延迟加载 Order 对象。即有一个 Order 对象,网站调用 myOrder.LineItems。
我的第一个想法是订单对象会调用订单服务来获取订单项,但这不是好的设计,因为对象需要了解服务,而服务需要了解对象。自然地,网站可以调用订单服务,将订单/订单 ID 传递给它以获取订单项,但我们如何才能让这一点不可见呢?所以 Order 对象保存了它的所有数据,但有些只在需要时加载?
谢谢,希望一切都有意义。
乔恩
最佳答案
作为面试官,我会在答案中寻找三件事。
- 了解 ORM 框架如何处理延迟加载
- 确认您不会在不考虑现有框架的情况下在生产环境中实现它。
- “本土”解决方案的实际设计。
我会这样回答这个问题。
延迟加载由 NHibernate 或 Entity Framework 等 ORM 框架实现的一项常见功能。我的第一次尝试是使用其中一个框架(第 1 点)
如果 ORM 框架是不可能的,我会使用像 CaSTLe Interception 或 Unity Interception 这样的拦截框架来实现延迟加载。(第 2 点)。
要从头开始实现延迟加载,我会使用 Decorator 模式(奖励点),继承 Order 类并在其中定义延迟加载行为。这是显示相关属性的设计:
class Order {
public int ID {get;set;}
public virtual IList<OrderLine> Lines{get;set;}
}
interface IOrderRepository {
Order GetOrder(id);
IList<OrderLine> GetOrderLines(Order order);
}
class OrderService {
IOrderRepository _repository;
public OrderService(IOrderRepository repository) {
_repository = repository;
}
public Order GetOrder(int id) {
return new OrderDecorator(_repository.GetOrder(id));
}
}
public class OrderDecorator : Order {
public OrderDecorator (IOrderRepository repository) {
_OrderLines = new Lazy<IList<OrderLine>>(()=>repository.GetOrderLines(this));
}
Lazy<IList<OrderLine>> _OrderLines;
public override IList<OrderLine> Lines {
get {
if (base.OrderLines == null)
base.OrderLines = _OrderLines.Value;
return base.OrderLines;
}
set {base.OrderLines=value;}
}
}
这是没有 Lazy<>
的版本幻想。在编辑以确保代码严格符合装饰器模式后,惰性版本实际上并没有添加任何东西,所以我只使用下面的版本。
public class OrderDecorator : Order {
public OrderDecorator (IOrderRepository repository) {
_Repo = repository;
}
IOrderRepository _Repo;
public override IList<OrderLine> Lines {
get {
if (base.OrderLines == null)
base.OrderLines = repository.GetOrderLines(this);
return base.OrderLines;
}
set {base.OrderLines=value;}
}
}
更新 这是项目布局。有关于耦合订单和存储库的评论。实际上并非如此,因为存储库耦合到装饰器,而不是顺序。
- 对象收集项目
- 订单
- 订单项
- 服务层
- 订单服务
- 存储库层
- 订单库
- OrderDecorator
关于c# - 对象在自己的DLL中时如何实现自己的延迟加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4810629/