WCF RIA Service随想

       强烈声明:本文对除第5条之外的任何内容不负责任,你只能作为参看,如果有被误导,自行负责!

       本文纯属虚构,如有雷同,纯属巧合!

 

 

       下面是个人基于学习的理解,有些不一定是正确的解释和描述,可以作为你学习的参考,不正确的还望指出:

       1,RIA Service基于WCF,但是有一点新的概念
       其实我对于WCF的配置和概念到现在不是很明白,主要是同事说,只要这样配置就行了,其他的不用去了解。再加上觉得配置很麻烦,不可理解,我相信有很多人和我一样的感觉。
       但是WCF其实一种很不错的,不同的应用程序交互的方式。因为其遵循“SOAP,WSDl和WS-*的标准,使得Service可以跨平台读取和使用,所以不仅MS支持,IBM等其他公司也都支持和参与了这些标准的指定。
       熟悉WCF的朋友就知道,WCF服务通过WSDL这种大家遵循的标准来定义一个服务的参数类型和返回值类型,通过遵循这个标准的定义,各个厂商的开发和应用平台就可以按这样的方式读取和使用。并且,这样的定义语言,各种语言很容易生成访问的代理类,例如VS的Add Service Reference帮我们生成的代理类,使我们不需要自己构造HttpWebRequest或者WebClient的方式去访问服务。
       但是我们知道,WCF封转的是一个方法,它就像一个处理,一个服务执行某个特定的任务。这种方法的定义千奇百怪,而且WCF本身只支持GET和POST,这使得它虽然使用起来是容易的,但是它并不遵循Web的某些指导原则。所以很多人认为REST才是未来,因为REST实际上是Web的最佳体验,一个URI代表某种资源,其使用HTTP动词GET,POST,PUT,DELETE,HEAD来代表对资源的不同处理方式,这统一了接口。统一接口的好处是大家都遵循同样的方式,一个URI代表某个资源,URI+HTTP Method+Body,这样的服务使用方式很明确。你很容易通过HttpWebRequest来构造一个REST API的请求。但是SOAP中,一个URI代表很多处理,通过在Body中来定义参数和要访问的方法,这样本身使得第三方很难去构造这种访问,基本上剩下唯一的方式就是生成代理类,这使得WCF很广泛在企业内部使用,但是真正的分布式应用或者跨平台的却很少使用WCF的方式,例如你随便翻看Google,校内,开心网,Facebook之类的开放API,它一定是REST的。
       基于这样一些东西,微软在近几年也加强了对REST的支持,大家可能很少听说OData,这就是微软自己的支持REST的数据协议,而更重要的像WCF Data Service完全基于Odata,使得企业可以以WCF的方式来提供REST服务。我们看到Windows Azure的所有API都是REST的。
       RIA Service和WCF Data Service一样的,它也提供REST服务,在RIA Service中,不再是我们随意定义自己的方发名称,而是必须遵循一定的规则。虽然函数名称仍然是可以自定义的,但是,重要的是,在WCF中每个方法一定对应一个HTTP动词,因为RIA Service会用来向外提供REST服务,它必须统一每个方法的接口,这样才能用统一的HTTP动词来对应到某个方法。而不像WCF,因为WCF不知道每个方法代表的是查询,或者新增,或者删除,更新,所以它只是去根据参数和方法名词去调用对应的方法,这导致了WCF本身的使用不方便,接口不统一,资源地址不明确等一些缺点。


       2,为什么WCF Data Service?为什么RIA Service?
       WCF本身有什么缺点嘛,为什么微软要花比较大的精力构建WCF Data Service。
       WCF本身已经是比较成熟的方案,至少就WCF的目标来说,它是比较完善和成熟的。
       从上面的分析来看,基于SOAP的方式是早期基于跨平台协作的提议,一些公司包括IBM,微软,Sun等巨头一起制定的数据交互协议。但是我们看到,REST才是跨平台,多系统协作的完美方案,所以借用以为博友的话”WCF的未来是RESTful,RESTful将是一等公民“。
       那么WCF Data Service和WCF RIA Service正是基于WCF的一种提供REST服务的方案,我们仍然按照熟悉的方式去开发,但是RIA Service能帮助我们提供基于WCF的REST式的API,而微软的REST遵循OData协议,遵循OData协议的好处是什么,除了遵循一般的REST风格,还支持微软的利器LINQ集成查询,使得我们可以使用LINQ对基于WCF Data Service或者WCF RIA Service的REST API进行查询和操作。


       3,怎么样实现基于WCF的REST API支持?
       但是,目前微软不可能开发一套新的方案,使我们直接就使用新的方案直接构建REST服务。
       至少说,WCF现在技术比较成熟,使用者也比较多,所以微软的做法是基于WCF来构建REST服务。
       事实上,我们还是使用原来WCF的方式去构建服务,我们并没有去定义这个方法代表GET,那个方法代表PUT,但是看看DomainService的使用方式,发现多了一些限制--每个方法名词必须遵循一定的方式,例如以Create,Update,Delete等开头,或者我们要构造自己的方法名称,但是必须声明方法某种特性。实际上这就是微软RIA Service在指导我们构建REST式的API,这样在RIA Service中,我们定义的每个方法都具有明确的动词,有了这个基础,RIA Service就很容易把我们本身是WCF一样定义的服务转化为REST服务。
       其实现机制,我们添加一个DomainService,再看一下Web.config,发现多了一个DomainServiceModule,是的,RIA Service将一般的WCF服务转化为REST服务就是通过它来处理的,DomainServiceModule接收REST请求,根据资源名称,HTTP动词,再加上我们对每个DomainService中每个方法的明确含义,DomainServiceModule就能找到对应的方法。通过这样的方式,RIA Service将给予WCF的服务转化成了REST服务。从而保护我们开发者的技术投资

 

       4,为什么RIA Service?
       其实如果是转化为REST API,这不就是WCF Data Service的使命吗,为什么又要特别拿出一个RIA Service。
       一看到RIA三个字,我们就知道是支持Silverlight的,其实,RIA不仅仅是为了Silverlight推出的,它用于所以的客户端访问,比如Ajax,RIA Service可以返回Xml和Json两种数据格式,这使得RIA客户端能够轻松的读取和使用数据。
       对于Silverlight来说,它还解决一个重要问题,用WCF来开发Silverlight应用程序的朋友一定经历过这样的事情,我们往往在服务端来定义逻辑处理,在Silverlight中调用不同的WCF方法,但是其实逻辑应该是在客户端,因此这往往使得我们的服务端的WCF定义会非常复杂,而且需要经常改动,更要命的是,对于WCF重要的问题是,通常我们不好去维护那些通信类,这些往往都是自动生成的,添加一些如Attribute或者自定义字段往往在重新更新数据服务之后就没了,所以通常一般的人都会在服务端和客户端另外构建实体,如此又要做WCF实体到自定义实体的转换,总之,这些工作看起来都那么让人讨厌,如果我们花时间去发挥自己的创意设计一段自己的程序,哪怕代码质量不高,起码我们自己感到心里舒服,但是,做那样的工作,我相信你的鼻子一定在出着粗气。
       我们以前就还准备做自己的VS工具,比如添加对Entity的右键,使在更新Entity的同时去更新我们自己维护的实体类,并修改相关的转换,My Lady Gaga

       这是WCF RIA Service出现了,它使我们可以单独定义字段的属性,对字段的验证逻辑,而且这样的验证逻辑可以同步到客户端,使得数据验证不仅发生在客户端,也发生在服务端,而且这样的自定义可以保留,不受任何黑暗势力的控制。这为我们带来了不少愉悦,并减少了很多焦虑。
       WCF RIA的另一个重要的功能源于它的REST API,我们前面说过,微软的RIA Service的REST API完全基于OData,而基于OData协议的REST API可以被LINQ支持,这使得我们可以将逻辑放在客户端,比如我们想构建一个查询,只需要在客户端构建不同的LINQ表达式,而不是要像以前一样在服务端建立一个新的方法,事实上,我们在服务端只需要放置一个一个实体的数据集,一个新增,删除,更新的方法,我们就可以在客户端构建不同的逻辑,因为RIA Service会将LINQ表达式翻译成相应REST API的调用。这样我们就又省了不少事,更不要说RIA Service还直接支持绑定,My Lady gaga!
       这里说一下LINQ,为什么什么东西都可以LINQ,是不是微软为每一张技术都实现一种LINQ,使我们使用起来是统一的。这里当然不是,所有的LINQ都是一样的,LINQ本身只记录一个表达式,通过查询表达式可以翻译成不同的内容,比如对于SQL就翻译成SQL语句,对于RIA Service就翻译成相应的REST API的调用,而对于其他技术,你仍然可以翻译成你想要的对表达式的解释,比如对于Windows Azure的Table,我们翻译成对Table API的访问,理论上,你可以构建自己的Linq To 你的东西。

 

       5,RIA Service本身的项目结构支持服务重用

       前面我说过,我对WCF其实不是很在行,我不知道一个WCF是否可以单独放在一个程序集,然后一个网站只需要引用这个程序集即可以使该网站提供相应的服务,这好比类似将一个ASP.NET的应用程序放在一个程序集,然后放在另一个空白的网站,是否这个网站也可以使用那个网站的功能。

       这些都没有去实践过,但是我想ASP.NET也好WCF也好都是基于文件名的资源寻址,只不过不同的后缀名使IIS选择不同的IHttpHandler来处理,我想如果这个.svc的文件放在一个程序集中,应该是无法路由的。

       但是RIA Service却不一样,你可以把一个Service完全放在一个程序集中,某个网站只要引用这个程序集,这个网站就可以对外提供这样的服务,我们看这是为什么?

       RIA Service用DomainServiceModule来处理请求,DomainServiceModule根据HTTP动词和URI来确定定位到某个方法,而在RIA Service中,为了定位到DomainService文件,RIA Service利用的不是文件定位,而是通过反射找到程序集和类,因为RIA Service的URI不是文件的路径,而是DomainService所在的命名空间,比如:

       namespace XXX.Services

      {

            public class DomainService1:DomainService

            {}

      }

       这样的服务路径不是看你将该类文件放在什么位置来作为文件路径,而是以命名空间来确定路径,它的路径就是:

       http://www.xxx.com/xxx-Service-DomainService1.svc

       我们看到,URI表明我要请求的类的命名空间,你只要到这个命名空间下面找到这个类反射就可以可以找到对应的方法处理我的请求。

       所以,这样基于程序集而不是基于文件路径,使得服务可以编译成程序集在其他网站重用。

       所以,RIA Service新增一个工程,用于建立RIA Service Class Library,而且不仅服务可以放在单独的项目,而且连代理类也放在不同的项目,这样使得代理类也可以重用。

       这使得在多个网站需要部署统一服务的特别方便,比如均衡负载或者多服务器的情况,每个后端服务器都要提供相同的服务,这是不是很好的特性呢!

 

      6,总结

      本文并没有描述RIA Service的技术细节,相信跟着一些博客的教程或者SDK,你可以去学习操作。本文只总结一些相关概念,有助于你理解。

      但是千万不要轻易相信我的话,我是一个菜鸟,有一些可能是理解错误的,只能作为参考,也欢迎拍砖!

      RIA Service还包含身份验证等等技术细节,有待你去一个一个掌握,期望对大家理解有一点点的帮助!

posted on 2010-11-07 21:45  秦春林  阅读(5096)  评论(17编辑  收藏  举报

导航