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

时间:2016-12-16 20:55:56

标签: c# icomparer

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

一个名为问题的表格将排序顺序信息存储在 QuestionId SortOrder 中。

另一个表 ApplicantQuestions 包含所有问题和答案,引用第一个表格 QuestionId

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

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

intellisense要求我为IRepository<Question>添加一些参数。

如何处理?是否可以在IComparer类内进行注射?

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

如何隐藏工厂后面的存储库?结构图将为您解决所有问题。

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

顺便说一下,除非你想在很多地方重复使用它,否则我不会把这个逻辑放在比较器中。我总是想在非常简单的情况下使用comparer而没有任何外部依赖。