Note: The examples below are C# but this problem should not be specific to any language in particular.
So I am building an object domain using a variant of the S# Architecture. For those unfamiliar with it, and to save you some reading time the idea is simply that you have a Data Access Object Interface for each of your domain objects that is responsible for loading to/from the persistence layer. Everything that might ever need to load/save a given object then accepts that object's data access interface as a dependency. So for example we can have the following where a product will lazy load the customer that purchased it as needed:
public class Product {
private ICustomerDao _customerDao;
private Customer _customer;
public Product(ICustomerDao customerDao) {_customerDao = customerDao;}
public int ProductId {get; set;}
public int CustomerId {get; set;}
public Customer Customer {
get{
if(_customer == null) _customer = _customerDao.GetById(CustomerId);
return _customer;
}
}
public interface ICustomerDao {
public Customer GetById(int id);
}
This is all well and good until you reach a situation where two objects need to be able to load each other. For example a many-to-one relationship where, as above, a product needs to be able to lazy load its customer, but also customer needs to be able to get a list of his products.
public class Customer {
private IProductDao _productDao;
private Product[] _products;
public Customer(IProductDao productDao) {_productDao = productDao;}
public int CustomerId {get; set;}
public Product[] Products {
get{
if(_products == null) _products = _productDao. GetAllForCustomer(this);
return _products;
}
}
public interface IProductDao {
public Product[] GetAllForCustomer(Customer customer);
}
I know that this is a really common situation but I am relatively new at this. My stumbling block is what to do when implementing the Data Access Objects. Because a Customer has a dependency on IProductDao, the CustomerDao implementation must also, however the vice versa is also true and ProductDao must take a dependency on ICustomerDao.
public class CustomerDao : ICustomerDao {
private IProductDao _productDao;
public CustomerDao(IProductDao productDao) {_productDao = productDao;}
public Customer GetById(int id) {
Customer c = new Customer(_customerDao);
// Query the database and fill out CustomerId
return c;
}
}
public class ProductDao : IProductDao {
private ICustomerDao _customerDao;
public ProductDao (ICustomerDao customerDao) {_customerDao = customerDao;}
public Product[] GetAllForCustomer(Customer customer) {
// you get the idea
}
}
And here we have the problem. You cannot instantiate CustomerDao without an IProductDao and vice versa. My inversion of control container (Castle Windsor) hits the circular dependency and chokes.
I have come up with a for-the-time-being solution which involves lazy loading the DAO objects themselves (I will post this as an answer) but I don't like it. What are the time-tested solutions to this problem?
EDIT: The above is a simplification of the architecture I'm actually using and I am not recommending someone actually pass DAOs to an object. A better implementation closer to what I am actually doing is similar to the way NHibernate works where the actual objects are very simple and the above are actually proxy objects which inherit and override the appropriate fields.