I have a project in which I am experiencing a circular reference problem.
I have an "Event" object in which I can have a list of "Question" objects I have a "Question" object from which I can obtain the parent "Event".
If I was using Entity Framework, it would be managed by the Framework, but I have a requirement to NOT use Entity Framework, for some reason, from my client. So, I tried to simulate the EF behavior because I am pretty sure they will eventually come to their senses and let me use EF. Here is how I proceed
public class EventRepository : AbstractRepository<Event>, IEventRepository
{
private readonly IQuestionRepository questionRepository;
public EventRepository(IContext context, IQuestionRepository questionRepository)
{
this.questionRepository = questionRepository;
}
public Event GetNew(DataRow row)
{
return new GeEvent(this.questionRepository) { // Load the event from the datarow }
}
public class GeEvent : Event
{
private readonly IQuestionRepository questionRepository;
public GeEvent(IQuestionRepository questionRepository)
{
this.questionRepository = questionRepository;
}
public override List<Question> Questions { get { return this.questionRepository.GetByIdEvent(this.IdEvent); }}
}
}
public class QuestionRepository : AbstractRepository<Question>, IQuestionRepository
{
private readonly IEventRepository eventRepository;
public QuestionRepository(IContext context, IEventRepository eventRepository)
{
this.eventRepository = eventRepository;
}
public Question GetNew(DataRow row)
{
return new GeQuestion(this.eventRepository) { // Load the question from the datarow }
}
public class GeQuestion : Question
{
private readonly IEventRepository eventRepository;
public GeQuestion(IEventRepository eventRepository)
{
this.eventRepository = eventRepository;
}
public override Event Event { get { return this.eventRepository.Get(this.IdEvent); }}
}
}
So, as you may see, I have a case of "the chicken or the egg". To create an EventRepository, it needs a QuestionRepository and to create a QuestionRepository, it needs an EventRepository. Other than using the DependencyResolver directly, which would make the repositories (and services) impossible to test properly, how can I manage the dependencies so I can load my foreign keys "a la" Entity Framework?
BTW, I have simplified the "lazy loading" of the foreign keys to keep the sample simple.
BTW2 I use Autofac, if it can help in anything.
Thanks
May I suggest that you are doing your design wrong? It appears to me that you're violating the Separation of Concerns principle when it comes to the repository.
A Question repository's job is not to give you the Event object which is the parent, but merely the eventId from which a user can query the EventRepository to get the Event Object. Similarly, for the other repository. That way, you don't have to go around passing dependencies but can compose your requests such as:
var question = _questionRepo.GetNew(row);
var evnt = _eventRepo.Get(question.IdEvent);
Also, Autofac does not officially support circular constructor\constructor depencies as you can read here.
Another solution is to change one of the dependencies to a Property setter and then proceed as shown in the document.