C#函数有条件地返回不同的模型-存储库模式

时间:2018-11-30 15:51:46

标签: c# asp.net-mvc repository-pattern

我在.NET MVC项目中使用存储库模式,在该项目中,我需要使用相同的功能但有两个不同的结构(有条件地)来获取数据。

更具体地说,在某些情况下,我需要获取具有一堆属性的完整版本的模型,但在某些情况下,我需要获取简单的模型版本(主要出于安全原因)。

到目前为止的代码:

public async Task<IEnumerable<AnswerMinimalDto>> GetQuestionsForUser(int userId)
{
    IEnumerable<Answer> foundAnswers = await this.repository.getAnswersByUser(userId);

    return Mapper.Map<IEnumerable<AnswerMinimalDto>>(foundAnswers);
}

因此,映射应有条件地发生:

....return Mapper.Map<IEnumerable<AnswerMinimalDto>>(foundAnswers);

....return Mapper.Map<IEnumerable<AnswerFullDto>>(foundAnswers);

在这里,我们有两个面向对象的原则相互冲突。首先想到的是要采用两种不同的方法来满足“单一责任”原则。另一方面,通过两种不同的方法完成相同的工作是重复的。

我将采用单一方法。到目前为止,我一直在尝试使用Tuples返回两个模型并从控制器处理所需结果的方法(由于我的方法是异步的,因此无法应用)。但是我对这种方法并不满意。

到目前为止,我想知道是否有任何一种优雅/可取的方式来返回有条件选择的不同结构中的数据。

欢迎任何帮助。

2 个答案:

答案 0 :(得分:2)

  

具有两种不同的方法来完成相同的工作是重复

但是他们没有做同样的工作!一个给您更多数据,另一个给您更少数据。我认为这是两件事。

还试图让控制器决定向客户呈现的内容是一种气味-业务逻辑已向控制器阐明。

正如您所说-您可以有2种方法提供不同的数据。但我走得更远,将接口分开:一个接口,两个实现。 IRepositoryFullRepositoryImplFrugalRepositoryImpl

然后让您的DI决定当前需要哪个,因为我敢打赌,这不是一次需要提供有限数据集的情况。

答案 1 :(得分:1)

您可以使用泛型简单地解决此问题:

public async Task<IEnumerable<T>> GetQuestionsForUser<T>(int userId)
{
    IEnumerable<Answer> foundAnswers = await this.repository.getAnswersByUser(userId);

    return Mapper.Map<IEnumerable<T>>(foundAnswers);
}

IEnumerable<AnswerMinimalDto> a = await GetQuestionsForUser<AnswerMinimalDto>(foundAnswers);
IEnumerable<AnswerFullDto> b = await GetQuestionsForUser<AnswerFullDto>(foundAnswers);

尽管我非常同意trailmax says on this TBH

IMO DTO对象和Automapper是代码气味/反模式。为什么不只返回基础对象?