IRepository Aggregates和Lazy Loading

时间:2011-11-18 20:14:25

标签: c# lazy-loading repository-pattern

我一直在整天搜索stackoverflow和互联网关于IRepository模式,试图在我尝试使用它之前更好地理解它。

从我读过的内容(如果我弄错了,请纠正我),一个repoistory封装了对其聚合根和子对象的访问,暴露了一个可以注入或模拟的公共接口。

因此,在您拥有聚合根对象的实例中:

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的平面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 / Entity Framework / ORM为你做”。

提前致谢。

d

1 个答案:

答案 0 :(得分:2)

真正的延迟加载意味着你可以在聚合根的属性中引用代理对象(以及懒散加载的对象图中的任何其他位置),这些对象足够智能,可以加载真实实体并替换代理在调用需要它的属性时使用它。使用诸如castle的动态代理或linfu的动态代理之类的东西是最好的方法,因为动态代理是由这些人很好地实现的复杂动物。

执行您的建议要求您的消费代码了解已加载和未加载的内容,并使用户负担了解延迟加载并在客户端代码中考虑它。使用动态代理,您无需考虑它。

实际上,最好的答案是你已经找到的答案。这是ORM解决的问题。使用NHibernate并担心你的域而不是实现已经实现并经过充分测试并被大量其他项目使用的东西。这是一个很多细微差别的问题,你最好不要使用已有的东西。