服务层仅返回模型

4

服务层应该只返回模型对象吗?网络上有一些关于此问题的帖子(这里这里是一些SO帖子),但没有一个好的例子。

我看到的都是像这样的东西:

服务应该只关心问题领域,而不是呈现结果的视图。返回值应该用领域对象而不是视图来表达。

我感觉我在这里漏了什么。

看下面的例子...假设我想返回所有电影的列表,但我需要一个布尔标志-类似于hasLike - 来显示我以前是否喜欢它。如何从服务层仅返回模型?

简而言之...如何按照这种方法从服务层返回元信息?是否可能?

模型

public class Person
{
    public int                     PersonID        { get; set; }
    public string                  Name            { get; set; }
    public ICollection<Movie>      FavoriteMovies  { get; set; }
    public ICollection<MovieLikes> Likes           { get; set; }
}

public class Movie
{
    public int      MovieID     { get; set; }
    public string   Name        { get; set; }
    public string   Description { get; set; }
}

public class MovieLike
{
    public int              MovieLikeID      { get; set; }
    public int              PersonID         { get; set; }
    public int              MovieID          { get; set; }
    public DateTimeOffset   Date             { get; set; }
}

服务

public class MovieService : IMovieService
{
    public Movie Get(int id)
    {

    }

    public Movie GetByName(string name)
    {

    }

    public IEnumerable<Movie> GetAll()
    {
        return unit.DbSet<Movie>();
    }
}

嗯...但如果我这样做,会向控制器传递不必要的数据,对吧? - Felipe Miosso
这里是你问题的可能答案:https://dev59.com/U2Ei5IYBdhLWcg3wK5rd - Hasteq
1个回答

2
你可以将服务分为查询和命令。查询操作返回扁平化的非规范化数据视图,易于客户端使用。命令操作接受包含执行命令所需信息的命令。
这意味着你从服务返回的查询模型与数据库中的模型不同。你可以随意添加属性,例如,在服务中执行的某些业务逻辑(或最好是业务层)设置的HasLike属性。因此,如果对客户端没有附加值,则无需返回点赞列表;而是根据是否有点赞将HasLikes设置为true或false。
因此,你在示例中提供的模型类(Person、Movie、MovieLike)是它们在域中和/或数据库中的外观表示,而不是从服务返回的模型类。相反,你可以有:
 public IEnumerable<MovieSummary> GetAll()
 {
     return unit.DbSet<Movie>();
 }

 // All properties needed in summarized representation
 public class MovieSummary
 {
     public int MovieID { get; set; }
     public string   Name { get; set; }
     public string   Description { get; set; }
     public bool HasLike { get; set; }
     // Other calculated properties
 }

并且...

 public MovieDetails Get(int id)
 {

 }

 // All properties needed in detailled representation
 public class MovieDetails
 {
     public int MovieID { get; set; }
     public string   Name { get; set; }
     public string   Description { get; set; }
     public ICollection<MovieLikes> Likes { get; set; }
     // more
 } 

以最优化的方式设计服务合同,使客户能够使用,这会让你的生活变得更加轻松。


所以,如果我理解正确的话...你是说要返回只有ViewModels而不是Models? - Felipe Miosso
我不会真的返回视图模型,因为它们只针对特定的视图;服务操作可以返回一个可以被多个客户端/视图使用的模型。但是要将其展示为扁平化的视图,而不是数据层次结构,只返回所需的内容,并在需要时添加类似HasLikes的概念。 - L-Four

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接