【问题标题】:Using Repositories and service references in MVC controllers在 MVC 控制器中使用存储库和服务引用
【发布时间】:2011-11-07 13:00:14
【问题描述】:

我在为我的 mvc 应用程序决定解决方案时遇到了一些麻烦。

背景。

我们有一个 EF 模型,我们通过 WCF 服务(不是数据服务)对其执行操作。

我有一个 MVC 应用程序,它有许多直接与服务对话的存储库,并将 WCF 类型返回给调用存储库方法的控制器,例如称为 WCFUserEntity 的类型(它实际上没有以 WCF 为前缀)。

在控制器内部,我计划将 WCFUserEntity 自动映射到 ViewModel 实体。

这个解决方案让我烦恼的是,因为我将 WCFUserEntity 返回到控制器,所以我必须在我的控制器中引用 WebService 代理,这对我来说不太合适,我希望我的控制器能够对存储库从何处获取数据一无所知。所以我的另一个选择是在存储库中进行自动映射并将 ViewModel 实体返回给控制器,但我找不到太多支持这个想法的东西,所以我真正要寻找的是验证这个第二个解决方案或帮助第三次。

谢谢,多姆

【问题讨论】:

    标签: asp.net-mvc model-view-controller design-patterns repository


    【解决方案1】:

    您可能需要考虑第三种选择。

    ViewModelBuilders 的使用。

    在您的控制器中,它们会像这样工作:

    var myViewModel = myViewModelBuilder.WithX().WithY().Build();

    WithX 和 WithY 将是在内部(在构建器中,例如 WithCountriesList() 如果您想添加显示视图中的国家/地区的下拉菜单)向视图模型添加内容的方法,并且 Build 方法将返回内部视图模型在使用 WithXXX 方法添加所有位之后。之所以如此,是因为大多数时候您可能希望为下拉列表和不属于您的原始模型的内容(在本例中为您的 userEntity)添加列表。

    这样,您的控制器对如何构建视图模型一无所知,您的存储库也与视图模型无关。所有工作都在 Builder 中完成。不利的一面是,您需要为每个 ViewModel 创建一个 ViewModelBuilder。

    我希望这会有所帮助。

    【讨论】:

    • 您好,感谢您的评论。我明白你在说 Builder 方法,但我看不出它与让存储库构建 ViewModel 有什么不同,因为 Builder 必须知道 WCF 服务和 ViewModel 类型。
    • 恐怕没有办法解决这个问题。在您的应用程序中的某个时刻,您必须将一个转换为另一个,此时您需要了解两者。通过在构建器中执行此操作,您可以分离关注点,控制器进行控制,存储库返回数据,构建器构建您的视图模型。您的控制器对您的 WCF 实体一无所知,因此根据您的体系结构,您可能不必添加对它们的引用。通过将构建器和存储库放在另一层中,可以限制 WCF 实体的范围。
    【解决方案2】:

    我将如何处理这可能需要一些架构更改,但我建议您使用 WCF API 以返回 ViewModels 而不是实体。

    首先,请考虑带宽问题(如果您在 Azure 或云中托管 WCF,这将是一个问题)。如果您的 ViewModel 仅使用一些特定属性,为什么要浪费带宽返回其他数据?在高流量情况下,这可能会导致流量浪费,最终可能会花钱。例如,如果您的视图仅显示用户和他的问题,则没有理由通过网络发送他的电子邮件、答案、积分等。

    另一个需要考虑的问题是急切加载。通过让 WCF 服务返回一个 ViewModel,您知道您在一次访问 WCF 服务时就拥有了视图所需的所有数据(即使它与相关实体有关)。您无需获取WCFUserEntity,然后向WCF 询问与该特定用户相关的WCFDocumentEntities

    最后,如果您的 WCF API 是围绕 ViewModels 构建的,那么您将对所涉及的业务流程有更清晰的了解。你知道这个特定的请求(和系统中的视图)会给你这个特定的信息,如果你需要不同的信息用于不同的视图,那么你知道这是一个完全不同的业务请求,具有不同的业务需求。以堆栈溢出为例,很容易看出该业务流程正在向当前用户询问他的相关问题,而该业务流程正在向当前用户询问他的相关答案。

    在您的数据检索 WCF API 中使用 ViewModel 意味着您的前端层不一定知道数据来自哪里,它只知道它调用了业务流程并获得了所需的数据。据它所知,数据层直接连接到数据库而不是 WCF。

    编辑: 重新阅读后,这实际上看起来像是您的第三个选项。网络上的大多数研究都没有谈论这个选项,我不知道为什么,但是在你遇到了一些类似的挫折之后(加上这篇文章中列出的其他人),这就是我在业务层中采用的方式。它更有意义,实际上(恕我直言)更容易管理。

    【讨论】:

    • 嗨@KallDrex,感谢您的回答,听起来像是一个理想的解决方案。我应该说的是 WCF 服务也被 wpf 应用程序使用,也是 WF4 状态机的一部分,不幸的是,它非常完整,在某些时候也需要所有成员,所以我被他们困住了。跨度>
    • 啊,是的,不幸的是,这使得这不切实际。这在架构的早期开发中非常有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    • 2020-08-01
    • 2011-11-13
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多