【问题标题】:Service and Controller Methods Similar Operations服务和控制器方法类似的操作
【发布时间】:2013-03-08 18:04:38
【问题描述】:

我有一个消息服务,其中包含创建、列出、更新和删除等操作。

在这个服务中我有一个 ListByMember(int memberId) 方法。

我需要构建两个视图,一个仅列出消息的标题,另一个视图列出消息的标题和描述,另一个列出标题和已收到的消息答案总数.

我不知道我是否在服务层创建了一个方法并通过 DTO 将所有信息从消息实体传输到视图,并且在视图中我只显示我想要的字段,或者我是否在服务层独立于它自己的 DTO 和特定视图。

我害怕创建一个单一的服务方法,如果将来我需要一个特殊的消息列表,我将面临一个问题。

任何建议都会很好。

谢谢。

【问题讨论】:

    标签: asp.net-mvc


    【解决方案1】:

    视图/控制器操作不是放置业务逻辑的最佳位置。尝试在服务中使用三种方法,即使这意味着一些额外的代码。您已决定使用 DTO 来实现非常好的项目。您可以采用的一种方法是创建一个私有方法以从存储库中将 DTO 获取为 IQueryable 并通过公共方法公开它 举个例子

    // DTOs
    public class MessageSummaryADto
    {
        public int MessageId { get; set; }
        public string Title { get; set; }
    }
    
    public class MessageSummaryBDto : MessageSummaryADto
    {
        public string Description { get; set; }
    }
    
    // public methods
    public int GetMessageCount()
    {
        return GetMessageSummary().Count();
    }
    
    public IQueryable<MessageSummaryADto> GetMessageSummaryADto()
    {
        return GetMessageSummary().Select(m => new MessageSummaryADto { MessageId = m.MessageId, Title = m.Title });
    }
    
    public IQueryable<MessageSummaryBDto> GetMessageSummaryBDto()
    {
        return GetMessageSummary();
    }
    
    // the private method
    private IQueryable<MessageSummaryBDto> GetMessageSummary()
    {
        return yourMessageRepository.Select(m =>
            new MessageSummaryBDto {
                MessageId = m.MessageId,
                Title = m.Title,
                Description = m.Description
            }
        );
    }
    

    如果您不是 IQueryable 的粉丝,您可以将 dto 公开为 IList

    祝你好运

    【讨论】:

    • 您好,谢谢,所以在您看来,对于每个 DTO,我都有一个返回此 DTO 类型的服务公共方法?顺便说一句,如果您有一个 ViewModel 需要另一个实体的数据,让我们在博客 cmets 中说,您是否创建一个本地类,其中包含您只需要在本地 viewmodel 中的评论的详细信息并构建一个列表评论服务方法还是您使用使用评论服务方法的评论视图模型来做列表?我认为如果我需要额外的字段,使用外部评论类可能会限制未来的变化。提前致谢。
    • 嗨,如果只在视图中需要隔离博客的 cmets 的概念,我会在 UI 层创建一个 DTO,然后使用一个返回 IQueryable 的服务来投影它在控制器动作中。如果您有一个单独的 UI 服务层,那么您可能希望将模型从 UI 移动到 UI 服务层并在那里进行投影。我很想发布一个代码 sn-p 来描述这个概念,但是 so-cmets 提供的字符数量有限
    • 嗨,所以如果我理解你的建议 Domain -> Service Method -> Map Domain to DTO -> Controller Action -> Map DTO to ViewModel -> View for each "line" of action 我有这个线,对吗?如果需要,您可以编辑答案并完成。谢谢
    • 顺便说一句,您有任何可以使用 TPH 方法通过参数接收不同模型的 Create 方法的示例吗?
    【解决方案2】:

    我的第二个答案需要两个级别的服务,一个业务服务和一个 UI 服务。如果您有非常具体的 UI 处理(例如列表和网格等的投影和过滤器),您会希望使用这种方法。业务服务将公开更多通用方法,这对 UI 来说是中性的

    那么它是如何映射的;

    域对象(输出:业务对象)-> 业务服务(输出通用 DTO)-> UI 服务(UI 特定 DTO em>) -> 控制器动作 -> 视图

    将数据切片和切块的 UI 任务卸载到特定于 UI 的服务使 Controller Action 非常精简(应该如此);通常,如果您可以将控制器操作中的代码行数限制在 10~15 之间,那会很好

    将 UI 服务与代码业务服务分开将使您可以轻松拥有多个 UI。例如,当您的业务服务是 UI 中立时,您可以使用它来引导 ASP.Mvc 和 WPF 应用程序

    上述方法需要维护额外的层,但如果您想要清晰的分离,值得考虑

    干杯

    【讨论】:

    • 您好,谢谢,是的,但正如您所说,这需要付费。我认为这里的选项是为每个 DTO 提供一种服务方法。再次感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多