Autofac、循环引用和解析外键的设计

Autofac, circular references and design for resolving foreign keys

我有一个项目遇到循环引用问题。

我有一个 "Event" 对象,其中我可以有一个 "Question" 对象的列表 我有一个 "Question" 对象,我可以从中获得父对象 "Event".

如果我使用 Entity Framework,它将由框架管理,但出于某种原因,我的客户要求我不要使用 Entity Framework。因此,我尝试模拟 EF 行为,因为我很确定他们最终会明白过来并让我使用 EF。以下是我的处理方式

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); }}
    }
}

因此,如您所见,我有一个案例 "the chicken or the egg"。要创建一个 EventRepository,它需要一个 QuestionRepository,而要创建一个 QuestionRepository,它需要一个 EventRepository。除了直接使用 DependencyResolver 之外,这会使存储库(和服务)无法正确测试,我如何管理依赖项以便加载我的外键 "a la" Entity Framework?

顺便说一句,我简化了外键的 "lazy loading" 以保持示例简单。

BTW2 我用的是 Autofac,如果它能帮上忙的话。

谢谢

我可以说你的设计有问题吗?在我看来,您在存储库方面违反了关注点分离原则。

问题存储库的工作不是为您提供作为父对象的事件对象,而只是提供用户可以从中查询 EventRepository 以获取事件对象的 eventId。同样,对于另一个存储库。这样,您就不必四处传递依赖项,而可以编写您的请求,例如:

var question = _questionRepo.GetNew(row);
var evnt = _eventRepo.Get(question.IdEvent);

此外,Autofac 并不正式支持循环 constructor\constructor 依赖关系,您可以阅读 here

另一种解决方案是将其中一个依赖项更改为 属性 setter,然后按照文档中的说明进行操作。