I can't really find a satisfying solution for that problem. I have a n-layers application :
- UI
- Presentation (Domain Model used as DTO, ViewModels are then presented)
- Business Layer (Domain Model)
- Repository and DAL (Data Model)
My problem is that I need to work with full objects in my business layer. However I can't figure out what is the best way to load them. The question may look stupid - and perhaps it is - but I'm very puzzled by it. I have the following classes (just to illustrate):
public class Library
{
int ID {get;set;}
string Name {get;set;}
Book[] Novels {get;set;}
Book[] TextBooks {get;set;}
}
public class Book
{
int ID {get;set;}
Library[] SalePoints {get;set;}
string Name {get;set;}
string Type {get;set;}
}
And I have two Service Methods LoadLibrary and LoadBook whose aim is to populate these respective models. My problem is that it looks like I will get into an infinite loop. I'll explain myself right now.
I have pre-loaded domain models coming from the Repositories (The repositories convert the Data Models into domain models using valueinjecter (unflatenning), so basically the simple fields (int, string, etc..), are populated in the resulting domain model but the IEnumerable properties are not. That's why I'm finishing to load them in the Service Layer. (There are also two reaons why I can't fully load them in my repositories : 1/ I'm using a generic repository and 2/ The loading logic relay on business rules)
Let us say that I do the following :
public class LibrairiesProcessor
{
public Library LoadLibrairyObject(int ID)
{
Library l = UnitOfWork.LibraryRepo.GetByID(ID); // Only retrieve "simple" properties, here it will get the Name and the ID properties;
l.Novels = UnitOfWork.BookRepo.Get(b=>b.LibrairyID==l.ID && b.Type="Novel");
l.TextBooks= UnitOfWork.BookRepo.Get(b=>b.LibrairyID==l.ID && b.Type="TextBook");
for(int i=0;i<l.Novels.Count();i++)
{
l.Novels[i] = BooksProcessor.LoadBookObject(l.Novels[i].ID);
}
}
}
and
public class BooksProcessor
{
public Book LoadBookObject(int ID)
{
Book b = UnitOfWork.LibraryRepo.GetByID(ID); // Only retrieve "simple" properties, here it will get the Name and the ID properties;
b.SalesPoint = // Get From repo using the Unit of work
for(int i=0;i<b.SalesPoint.Count();i++)
{
b.SalesPoint[i] = LibrairyProcessor.LoadLibraryObject(b.SalesPoint[i].ID);
}
}
}
Isn't there an infinite Loop ? LoadLibraryObject() calling LoadBookObject() and vice versa... And especially when you come to the book whose SalePoint is the librairy who triggered LoadBookObject()... at best the same work is done twice, but I really suspect that it will never end.
So I'm wondering if I'm doing the things right. My goal is to have fully loaded objects to avoid wondering if the object is enough loaded before using it, but I'm not sure of the solution I've came up with. How do you usually achieve that ?
It looks like a trivial issue but seriously I can't figure out how to load my stuff. I feel like I have a dilemma :
1/ Manually Populating all the properties and sub properties by using UnitOfWork.Repository, but I will have a lot of code and a lot of redundant code.
2/ Live with partially loaded domain models with some properties set to null, but I really don't want that. And since I'm not working with EF objects directly since my domain model is complex, I can't use their lazy loading stuff.
3/Call the Service LoadObject Methods from one LoadObjectMethod to an other, to avoid code redundancy, but it looks like I'm introducing a lot of recursivity.
How should I handle that ?
Thanks !