【问题标题】:ASP.NET MVC - separating large appASP.NET MVC - 分离大型应用程序
【发布时间】:2011-02-04 19:51:16
【问题描述】:

我一直对我认为自相矛盾的术语感到困惑:ASP.NET MVC 声称正在推进和支持“关注点分离”的座右铭,我觉得这是个好主意。

但是,似乎没有办法将控制器、模型或视图分离到它们自己的程序集中,或者将区域分离为程序集。

使用 ASP.NET MVC 中固定的 ControllerModelView 文件夹,您实际上是在创建一个大杂烩。这真的是关注点分离吗?好像跟我完全相反。

所以我想知道的是:

  • 如何创建一个 ASP.NET MVC 解决方案,将控制器、模型和充满视图的文件夹分离到单独的程序集中?

  • 如何将 ASP.NET MVC 2 的区域放入单独的程序集中?

  • 或者您如何管理一个大型 ASP.NET MVC 应用程序 - 它有几十个甚至超过一百个控制器、大量模型和视图模型类以及数百个视图?

【问题讨论】:

    标签: asp.net-mvc separation-of-concerns


    【解决方案1】:

    我认为您正在寻找Areas in ASP.Net MVC 2。 CSProj 文件中有一些需要取消注释的内容,但之后它会在您构建时复制视图。我认为没有任何要求 ControllerModel 类与视图在同一个程序集中。

    Walkthrough: Creating an ASP.NET MVC Areas Application Using Multiple Projects

    【讨论】:

    • @Mark:谢谢 - 但是,这是否可以跨越程序集边界?例如。我可以将我的“管理员”和“超级用户”区域放入单独的类库中并从主 ASP.NET MVC2 应用程序中引用它们吗?我从来没有看到任何关于如何做到这一点的提示、截屏视频或演示......它总是只是你的单一、单一的 ASP.NET MVC2 应用程序中的子文件夹......
    • @marc_s 我知道每个 MVC 区域可以有不同的程序集。我们在这里这样做。我不知道你可以将控制器和模型放在他们自己的程序集中,但我看不出有什么理由不这样做。我认为区域构建任务只是将视图复制到主项目并提供一种注册路线的机制。 ...但这只是一个假设。我们实际上并没有使用构建任务并手动复制视图并且它可以工作。
    • @marc_s 我将链接添加到我遵循的演练中。
    【解决方案2】:

    控制器: AFAIK 你不应该做任何特别的事情来将控制器放入他们自己的程序集中。至多你所要做的就是覆盖你的 ControllerFactory 的 GetControllerType 方法。

    模型:对模型放置位置的零限制。尽管这令人不悦,但我经常使用来自 Nhibernate/其他 ORM 层或 WCF/服务层 DTO 的持久对象,它们位于单独的程序集中作为我的视图。这与使用 WebForms 的方式相同

    视图:必须将单独程序集中的视图标记为嵌入资源,然后您必须使用知道如何从资源而不是文件系统获取视图的自定义VirtualPathProviderviews from an resource instead of the file system。这又是您用于 WebForm 开发的完全相同的技术。

    关于 mcintyre321 和他的 Portable Areas 回答: 链接的项目几乎不做任何定制,只是简单地将现有的 MVC 2 扩展点包装成更易于使用的抽象。它几乎没有“自定义”和更多的语法糖。

    您管理大型 MVC 应用程序就像管理任何其他大型应用程序一样。我害怕打开一个 500 页的 WebForms 项目,因为你永远不知道每个代码背后的内容。使用 MVC,不同的功能大部分都在其正确的位置。一点也不矛盾。

    【讨论】:

    • @marc_s,我很高兴,我肯定会更深入地了解 MVC,您会看到所有可扩展性点确实让管理大型应用程序变得非常容易。 :D
    • 我从未真正考虑过将视图作为嵌入式程序集资源。如果您必须打包一个应用程序以进行交付,我可以看到这会很好。
    • @Mark,如果您有自定义输入实现,例如带有 javascript 日历小部件的 DateTime 字段并且您需要跨项目共享它,那就太好了。视图引擎非常智能,如果它们共享相同的路径,您还可以使用本地视图覆盖嵌入的视图。
    • 我也能看到。它使携带这些类型的部分视图变得非常容易,但我认为对每个视图都这样做是矫枉过正的。您失去了在不编译的情况下查看和/或更改标记的能力。区域对我来说感觉更自然。
    【解决方案3】:

    将代码分成单独的程序集与关注点分离是正交的。代码所在的位置不是“问题”。关注点分离与各个组件的职责和依赖方向有关。例如,视图负责渲染输出,控制器知道视图,但视图并不真正了解控制器。

    同样,模型对视图或控制器一无所知,但视图和控制器都会知道模型。

    但是,回到你的问题。正如 jfar 所指出的,将控制器和模型移动到另一个组件中非常容易并且会起作用。将视图移动到另一个程序集中比较棘手。具有自定义虚拟路径提供程序的嵌入式资源是一种方法,但我们通常不推荐用于高性能站点的方法。但是,如果它满足您的需求,那就去吧。

    【讨论】:

    • 感谢您的见解,菲尔。因此,要将控制器和/或模型移动到单独的程序集中,不需要额外的配置或初步步骤,对吧?
    • 没错。您只需要确保您的 MVC 项目引用您将模型和控制器移入的其他项目/程序集。
    • 定义:正交 /ôrˈTHägənl/ 形容词:属于或涉及直角;在直角。 (变量)统计独立。
    【解决方案4】:

    MVC 具有很强的可扩展性,不需要遵守 Controller、View 和 Model 文件夹结构。您可以将控制器放置在您想要的任何位置,但是如果它们位于另一个组件中,您将需要实现自己的控制器工厂,该工厂知道如何定位它们。 Here 是使用 Windsor 定位控制器的示例。

    您的模型/视图模型可以在您想要的任何地方。您只需要在 web.config 中引用它们的命名空间,以便视图知道在哪里查找。 (至少我知道 Spark 视图引擎是这样的。)

    您将您的观点放在任何网络项目中。我通常的策略是创建一个包含views 文件夹的普通Web(非mvc)项目。 (这甚至可能是一个遗留的网络应用程序!)然后我所有的控制器都放在一个单独的类库中。我的视图模型和服务放在另一个地方。

    就构建文件夹而言,我通常以域概念为中心。我会在每个项目中为用户、产品、订单等创建一个文件夹。我在任何地方都没有 Models 或 Controllers 文件夹。

    【讨论】:

    • @Ryan:如果我选择 not 来使用约定(控制器、模型、视图文件夹),我需要特别注意什么?这是约定优于配置 - 如果我不遵守标准约定,我需要配置一些东西吗?
    • 真正唯一的一点是实现你自己的控制器工厂。请务必在 global.asax 文件中设置正确的工厂。
    【解决方案5】:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    相关资源
    最近更新 更多