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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#函数有条件地返回不同的模型 - 存储库模式相关的知识,希望对你有一定的参考价值。

我在.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返回两个模型并处理控制器所需的结果(因为我的方法是异步的,因此无法应用)。但我对这种方法并不满意。

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

欢迎任何帮助。

答案

您可以使用泛型来解决这个问题:

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是代码味道/反模式。为什么不直接返回底层对象?

另一答案

有两种不同的方法做同样的工作是重复

但他们没有做同样的工作!一个给你更多数据,另一个给你更少的数据。在我看来,这是两件不同的事情。

同时试图让控制器决定向客户呈现什么是一种气味 - 业务逻辑被拼写到控制器。

正如您所说 - 您可以使用两种方法来提供不同的数据。但我会更进一步,并隔离接口:一个接口,两个实现。 IRepositoryFullRepositoryImplFrugalRepositoryImpl

让你的DI决定当前需要哪一个,因为我敢打赌,这不是你需要提供一组有限数据的单一事件。

以上是关于c#函数有条件地返回不同的模型 - 存储库模式的主要内容,如果未能解决你的问题,请参考以下文章

基于模型实例获取学说结果

c# 泛型类型和存储库模式

在每个模型的不同 DAL 类中实现 JPA 存储库方法时如何避免重复的代码行/代码块

c#Repository 模式:每个子类一个存储库?

使用 Mongoose 和 GraphQL 从填充模型有条件地返回值的最有效方法?

领域模型和实体框架之间的存储库模式和映射