如何在 C# IComparer class 中注入存储库?
How to inject repository in a C# IComparer class?
我需要按排序顺序对问题进行排序。
一个名为 Questions 的 table 将排序顺序信息存储在 QuestionId 和 SortOrder.
另一个 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
顺便说一句,除非您想在很多地方重用它,否则我不会将此逻辑放入比较器中。我一直想在没有任何外部依赖的非常简单的情况下使用比较器。
我需要按排序顺序对问题进行排序。
一个名为 Questions 的 table 将排序顺序信息存储在 QuestionId 和 SortOrder.
另一个 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
顺便说一句,除非您想在很多地方重用它,否则我不会将此逻辑放入比较器中。我一直想在没有任何外部依赖的非常简单的情况下使用比较器。