Repository pattern with lazying loading using POCO
I'm in the process of starting a new project and creating the business objects and data access etc. I'm just using plain old clr objects rather than any orms. I've created two class libraries: 1) Business Objects - holds all my business objects, all this objects are light weight with only properties and business rules. 2) Repository - this is for all my data access.
The majority of my objects will have child list in and my question is what is the best way to lazy load these values as I don't want to bring back unnecessary information if开发者_高级运维 I dont need to.
I've thought about when using the "get" on the child property to check if its "null" and if it is call my repository to get the child information. This has two problems from what I can see: 1) The object "knows" how to get itself I would rather no data access logic be held in the object. 2) This required both classes to reference each other which in visual studio throws a circular dependency error.
Does anyone have any suggestions on how to overcome this issue or any recommendations on my projects layout and where it can be improved?
Thanks
To do this requires that you program to interfaces (abstractions over implementations) and/or declare your properties virtual. Then your repository returns a proxy object for those properties that are to be loaded lazily. The class that calls the repository is none the wiser, but when it tries to access one of those properties, the proxy calls the database and loads up the values.
Frankly, I think it is madness to try to implement this oneself. There are great, time-tested solutions to this problem out there, that have been developed and refined by the greatest minds in .NET.
To do the proxying, you can use Castle DynamicProxy, or you can use NHibernate and let it handle all of the proxying and lazy loading for you (it uses DynamicProxy). You'll get better performance than out of any hand-rolled implementations, guaranteed.
NHibernate won't mess with your POCOs -- no attributes, no base classes; you only need to mark members virtual to allow proxy generation.
Simply put, I'd reconsider using an ORM, especially if you want that lazy loading; you don't have to give up your POCOs.
After looking into the answers provided and further research I found an article that uses delegates for the lazy loading. This provided a simpler solution than using proxies or implementing NHibernate.
Here's the link to the article.
If you are using Entity Framework 4.0, you will have support for POCO's with deferred loading & will allow you to write a generic repository to do data access.
There are tons of article online on generic repository pattern with EF 4.0
HTH.
You can get around the circular dependency issue if your lazy loading code loads the repository at runtime (Activator.CreateInstance or something similar) and then calls the appropriate method via reflection. Of course there are performance penalties associated with reflection, but often turn out be insignificant in most solutions.
Another way to solve this problem is to simply compile to a single dll - here you can still logically separate your layers using different namespaces, and still organise your classes by using different directories.
精彩评论