IRepository聚合和延迟加载
本文关键字:延迟加载 IRepository | 更新日期: 2023-09-27 18:15:04
我一整天都在浏览stackoverflow和互联网上关于IRepository模式的信息,试图在我愤怒地使用它之前更好地理解它。
从我所读到的(如果我错了,请纠正我),一个存储库封装了对其聚合根和子对象的访问,暴露了一个公共接口,然后可以被注入或模拟。
那么在你有聚合根对象的实例中:
class Employee {
string FirstName;
string LastName;
IEnumerable<Address> Addresses;
IEnumerable<PhoneNumber> PhoneNumbers;
}
那么它的子对象:
class Address {
string BuildingName;
...etc
}
class PhoneNumber {
string PhoneNo;
...etc
}
所以存储库看起来像这样:
class EmployeeRepository : IRepository<Employee> {
Employee Get(id) {
...does stuff, builds full Employee object including Addresses/Phone No's and returns
}
}
但是假设我不想获得整个Employee,假设我只想要具有FirstName LastName的flat Employee记录并且能够在稍后延迟加载其余的。如何做到这一点呢?是否允许这样写:
class EmployeeRepository : IRepository<Employee> {
Employee Get(id) {
...does stuff and builds flat Employee object without Addresses and Phone Numbers
}
Employee GetAddresses (Employee emp) {
...
}
Employee GetPhoneNumbers (Employee emp) {
...
}
}
这是可以的,还是我打破了一些神圣的DDD规则,在开发者的地狱里燃烧?如何延迟加载应该适合这个模型,再次尝试搜索,但我发现的是"让NHibernate/实体框架/ORM为你做"。
提前感谢。
d .
真正的延迟加载将意味着您在聚合根的属性中(以及您最终惰性加载的对象图中的其他任何地方)有对代理对象的引用,这些引用将足够智能地加载真正的实体,并在调用需要它的属性时用它替换代理。使用castle的动态代理或linfu的动态代理是最好的方法,因为动态代理是复杂的野兽,这些家伙已经很好地实现了。
做你建议的事情需要你的消费代码知道什么已经加载,什么还没有加载,这给用户带来了负担,让他们知道延迟加载,并在客户端代码中考虑它。使用动态代理,您不必考虑它。
实际上,最好的答案是你已经找到的那个。这个问题已经被orm解决了。使用NHibernate,担心你的领域,而不是实现一些已经实现、经过良好测试并被大量其他项目使用的东西。这是一个有很多细微差别的问题,你最好使用已经存在的东西。