如何在 C# IComparer class 中注入存储库?

How to inject repository in a C# IComparer class?

我需要按排序顺序对问题进行排序。

一个名为 Questions 的 table 将排序顺序信息存储在 QuestionIdSortOrder.

另一个 table ApplicantQuestions 包含所有问题和答案,通过 QuestionId 引用第一个 table .

所以基本上我们想根据另一个列表对列表进行排序。

public class QuestionOrderComparer : IComparer<int>
{
    private readonly IRepository<Question> _Questions;

    public QuestionOrderComparer(IRepository<Question> Questions)
    {
        _Questions = Questions;
    }

    public int Compare(int x, int y)
    {
        var questionsInOrder = _Questions.All
            .Select(q => new QuestionOrderModel(q.QuestionId, q.SortOrder))
            .ToList();

        var xValue = questionsInOrder.FirstOrDefault(q => q.Id == x)?.SortOrder ?? 0;
        var yValue = questionsInOrder.FirstOrDefault(q => q.Id == y)?.SortOrder ?? 0;
        return xValue - yValue;
    }
}

看起来不错,但当我尝试使用它时

thisSetOfApplicantQuestions
    .OrderBy(x => x.QuestionId, new QuestionOrderComparer());

智能感知需要我为 IRepository<Question> 添加一些参数。

如何处理?是否可以在 IComparer class 内注入?

转储比较器并将该代码放入问题集合对象的 Sort 方法中。

此代码将比较和排序混为一谈。传统上 class 覆盖 CompareTo,或者有一个客户比较器。 .net 框架知道在对一组问题调用 sort 时使用它。 "compare" 方法应该比较 - 返回 -1,0,1(分别小于、等于、大于) - 而不是进行实际排序。我可以看到 LINQ 改变了这种范式,但是,Compare 进行排序似乎仍然不利于框架。然后,Questions 集合应该有一个比较器,反之亦然。

将存储库隐藏在工厂后面怎么样?结构图为你解决一切

public class QuestionOrderComparerFactory : IQuestionOrderComparerFactory
    {
        private IRepository<Question> _questions;

        public QuestionOrderComparerFactory(IRepository<Question> questions)
        {
            _questions = questions;
        }

        public QuestionOrderComparer Create()
        {
            return new QuestionOrderComparer(_questions);
        }

    }



    thisSetOfApplicantQuestions.OrderBy(x => x.QuestionId, _comparerFactory.Create()); // comparer factory is injected via constructor

顺便说一句,除非您想在很多地方重用它,否则我不会将此逻辑放入比较器中。我一直想在没有任何外部依赖的非常简单的情况下使用比较器。