ASP.Net MVC以Web服务为模型?

时间:2009-06-01 20:21:02

标签: asp.net-mvc rest wcf-data-services

有没有人有关于在ASP.Net MVC应用程序中使用Web服务作为模型的建议或提示?我没有看到有人写这样做。我想构建一个MVC应用程序,但不是将它绑定到使用特定数据库,也不是将数据库限制为单个MVC应用程序。我觉得Web服务(RESTful,很可能是ADO.Net数据服务)是可行的方法。

4 个答案:

答案 0 :(得分:28)

您的MVC应用与数据库分离的可能性有多大?在应用程序生命周期中,您经常看到从SQL Server到Oracle的更改?从我交付的最近10年的项目开始,它从未发生过。

体系结构就像洋葱一样,它们在所依赖的东西之上有一些抽象层。如果您打算使用RDBMS进行存储,那么这就是您架构的核心。从数据库中提取自己,以便你可以交换它是一个非常谬误。

现在,您可以将数据库访问与域分离,而存储库模式是实现此目的的方法之一。目前大多数成熟的解决方案使用ORM,因此如果您需要成熟的技术,可能需要查看NHibernate,或者在数据之上使用ActiveRecord / linq2sql来查看更简单的活动记录模式。

既然您已经制定了数据策略,那么您就拥有了某种域名。当您向客户端公开数据时,您可以选择通过MVC模式执行此操作,您通常会在其中发送从域生成的DTO以进行呈现,或者您可以决定利用REST之类的体系结构样式来提供更松散耦合的系统,通过提供链接和自定义表示。

当你走向解决方案的外层时,你会从紧耦合变为松耦合。

但是,如果您的问题是在REST架构或Web服务之上构建MVC应用程序,并将其用作模型......为什么要这么麻烦?如果您要拥有域模型,为什么不在您的系统中重复使用它?

从MVC应用程序生成UI并生成RESTful架构所需的文档是两个完全不同的上下文,基于彼此的基础只会导致比需要更多的痛苦。你牺牲了表现。

取决于您的具体情况,但远程基于XML的服务作为MVC中的模型,从经验而不是一个好主意,它可能过度工程并且无视域的开始。

答案 1 :(得分:3)

编辑2010-11-27;澄清了我的想法,这是真正需要的。

Web服务通常在不同类型的应用程序中公开功能,而不是在单个应用程序中进行抽象。您可能更多地考虑以不干扰控制器/视图编程的方式封装命令和读取的方法。

如果您正在解耦并在异步页面中执行异步模式,请使用服务总线中的服务。你可以看到Rhino.ServiceBus,nServiceBus和MassTransit用于.Net原生实现,RabbitMQ用于不同的http://blogs.digitar.com/jjww/2009/01/rabbits-and-warrens/

编辑:我有一段时间以推送消息到我的服务的方式尝试兔子,这反过来推动了对预订应用程序的更新。 RabbitMQ是一个消息代理,也就是一个MOM(面向消息的中间件),您可以使用它将消息发送到您的应用程序服务器。

您也可以简单地提供服务接口。阅读Eric Evan的域驱动设计以获得更详细的描述。

REST-ful服务接口处理大量数据,更具体地说是可寻址资源。它可以大大简化您的编程模型,并允许通过HTTP协议很好地控制输出。 WCF即将推出的编程模型使用原始论文中定义的真正休息,其中每个文档在某种程度上应该为继续导航提供URI。有一个look at this。 (在我发布的这篇文章的第一个版本中,我感到遗憾的是“缓慢”,无论这意味着什么)基于REST的API也几乎是CouchDBRiak使用的。

ADO.Net相当废话(!)[懒惰集合的N + 1问题,因为代码到实现,数据访问泄漏 - 你总是需要你的查询代码所在的数据库上下文]与示例LightSpeed(商业)或NHibernate。 Spring.Net还允许您使用Web服务外观将服务接口包装在其包含中,但是(没有浏览它一段时间)我认为它的配置有点太过分了。

编辑1:在这里使用ADO.Net我指的是使用DataSet,DataAdapter和从DataReader迭代大量行的默认“最佳实践”;它会产生相当难看且难以调试的代码。 N + 1的东西,是的,这是关于实体框架的。

(编辑2:EntityFramework也不会让我印象深刻!)

编辑1:在单独的程序集中创建域图层[aka。核心]并提供所有域和应用程序服务,然后从您的特定MVC应用程序导入此程序集。通过核心程序集中的接口将数据访问包装到某个DAO / Repository中,然后数据程序集将引用并实现该接口。通过IoC连接接口和实现。您甚至可以使用上述服务总线为动态服务发现编程,以解决接口问题。 WCF使用这样的接口,大多数上述服务总线也是如此;您可以在IoC容器中提供一个subcomponentresolver来自动执行此操作。

编辑2: 对于上述内容的一个很好的组合将是CQRS + EventSourcing + ReactiveExtensions。您的写模型将接受命令,您的域模型将决定是否接受它们,它会将事件推送到reactive-extensions管道,也可能通过RabbitMQ推送,读取模型将使用它。

更新2010-01-02(编辑1)

我的想法的开玩笑被称为MindTouch Dream。他们制作了一个截屏视频,他们将Web应用程序的几乎所有部分都视为(web)服务,并通过REST公开。

他们创建了一个高度并行的框架,使用协同例程来处理这个问题,包括他们自己的弹性线程池。

对于这个问题中的所有同性恋者,在你的脸上:p! Listen to this screen-cast,,特别是在12分钟。

The actual framework is here.

如果您正在进行此类编程,请查看how monads worktheir implementations in C#。您还可以阅读CoRoutines

新年快乐!

更新2010-11-27(编辑2)

事实证明,CoRoutines通过Microsoft的任务并行库实现了产品化。您的任务现在实现了相同的功能,因为它实现了IAsyncResult。 Caliburn是一个很酷的框架,使用它们。

Reactive Extensions将monad理解提升到了下一级异步。

当我第一次写这个答案时,ALT.Net世界似乎正朝着我所谈论的方向发展,尽管有一些我不了解的新型架构。

答案 2 :(得分:3)

您应该以与数据访问无关的方式定义模型,例如:使用存储库模式。然后,您可以创建由特定数据访问技术(Web服务,SQL等)支持的具体实现。

答案 3 :(得分:0)

这实际上取决于这个mvc项目的大小。我想说如果网站将由少数用户使用(< 5000),则将UI和域保持在相同的运行环境中。

另一方面,如果您计划在数百万人访问的网站上,您必须考虑分布式,这意味着您需要以可扩展/扩展的方式构建您的网站。这意味着您可能需要使用额外的服务器(Web,应用程序和数据库)。

为了使其正常工作,您需要将mvc UI站点与应用程序分离。应用程序层通常包含您的域模型,可能通过WCF或服务总线公开。我更喜欢服务总线,因为它更可靠,可能使用像msmq这样的持久队列。

我希望这会有所帮助