1.自己用CAB的时候,由于对CAB底层机制尚未洞悉,有些地方用的总感觉别扭。比如,如果我希望用客户端保存(PersistenceService)的数据来初始化启动界面中的SmartPart控件,按理说我应该在控件的InitializeComponent()中访问控件所在的WorkItem,然后使用WorkItem调用持久化服务。但由于我是采用依赖注入的方式通过属性向SmartPart传入其所属WorkItem的引用,如代码段1:
 1日志 20071207(CAB,Data Transfer in WCF)//代码段1
 2日志 20071207(CAB,Data Transfer in WCF)
 3日志 20071207(CAB,Data Transfer in WCF)private BidListWorkItem parentWorkItem;
 4日志 20071207(CAB,Data Transfer in WCF)[ServiceDependency]
 5日志 20071207(CAB,Data Transfer in WCF)public BidListWorkItem ParentWorkItem
 6}
这个属性被注入的时间晚于控件的InitializeComponent()被调用的时间,所以前面所述方案不成立。目前我采用的方法列在代码段2,感觉上不好,虽然逻辑上不错但结构恶心。等自己把WorkItem和SmartPart之间初始化的整个流程都搞清楚了,再来重构吧。
 1日志 20071207(CAB,Data Transfer in WCF)//代码段2
 2日志 20071207(CAB,Data Transfer in WCF)
 3日志 20071207(CAB,Data Transfer in WCF)private BidListWorkItem parentWorkItem;
 4日志 20071207(CAB,Data Transfer in WCF)[ServiceDependency]
 5日志 20071207(CAB,Data Transfer in WCF)public BidListWorkItem ParentWorkItem
 6}

2.对于大文件的传输,现在脑子里有几个基本的概念:
 (1)要用Streamed的方式,不要用Buffered的方式
 (2)要使用二进制格式的原生信息,不要使用Base64进行信息的文本化处理
 (3)WCF本身考虑的是怎么对信息作编码,通过什么样的协议传过来。但续传本身的一些功能(比如把已经传过来的内容先一部分得保存起来等)可能需要自己去考虑它的实现方式。

3.如果使用MTOM作为一个binding的Encode方式,如代码段3:
日志 20071207(CAB,Data Transfer in WCF)<!--代码段3-->
日志 20071207(CAB,Data Transfer in WCF)
日志 20071207(CAB,Data Transfer in WCF)
<bindings>
日志 20071207(CAB,Data Transfer in WCF)    
<wsHttpBinding>
日志 20071207(CAB,Data Transfer in WCF)        
<binding name="ExampleBinding" messageEncoding="Mtom"/>
日志 20071207(CAB,Data Transfer in WCF)    
</wsHttpBinding>
日志 20071207(CAB,Data Transfer in WCF)
</bindings>
对于你传送的二进制流(byte[]),不管这个传送数据是通过如代码段4这样的方式以DataContract显示指定的,还是在一个Operation里面作为参数返回值,MTOM都是按照相同的策略对其进行处理:如果数据量够大(大到了可以负担MIME头等的开销),则使用二进制的MIME进行消息传送;否则依然采用Base64编码。
日志 20071207(CAB,Data Transfer in WCF)//代码段4
日志 20071207(CAB,Data Transfer in WCF)

日志 20071207(CAB,Data Transfer in WCF)[DataContract]
日志 20071207(CAB,Data Transfer in WCF)
class MyData
 
另外,如果自己理解的不错的话,MTOM考虑的只是消息内容的编码方式,但至于消息是按照Streamed还是Buffered的方式去发送和接收,与之无关。

4.使用Streamed的方式去发送消息,有几个明显的限制:
(1)无法对消息体进行签名。这是当然的,因为内存里不再缓存整个消息了。
(2)由于无法签名,所以一些依赖于签名的加密手段就不能使用了。
(3)难以支持整个消息的重发,因而也就无法保证一个可靠的连接(reliable session)
正因为有这些限制,所以WCF中的很多默认的Binding是不支持这种Streamed的方式的,只有下面三种绑定可以:BasicHttpBinding, NetTcpBinding, NetNamedPipeBinding。

5.对于TransferMode这个枚举值,第一次在MSDN的时候可是把俺为难坏了,啃了半天英文也没搞清楚到底哪种环境适合用什么,直到后来看到代码段5例子(我已添加注释):

 1日志 20071207(CAB,Data Transfer in WCF)//代码段5
 2日志 20071207(CAB,Data Transfer in WCF)
 3日志 20071207(CAB,Data Transfer in WCF)[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
 4日志 20071207(CAB,Data Transfer in WCF)public interface IStreamedService
 5*/

另外,这也纠正了我以前的一个误区。我以前认为ServiceContract和Binding是一一对应的,或者说,我认为如代码段6这样的配置中的contract属性只能指向一个ServiceContract,看来我是错的(还需以后的验证)。

日志 20071207(CAB,Data Transfer in WCF)<!--代码段6-->
日志 20071207(CAB,Data Transfer in WCF)
<endpoint address="http://service.eally.com.cn/GEAWCFServiceHost/WCFService.svc" binding="basicHttpBinding" 
日志 20071207(CAB,Data Transfer in WCF)     bindingConfiguration
="StreamedHTTP"
日志 20071207(CAB,Data Transfer in WCF)     contract
="BitAEC5.WCFService.TenderBidService.ITenderTopicList"/>

 

6.自己到目前为止,在开发中还没有用过DataContract和MessageContrace,说明自己对WCF的理解和使用都非常片面,有很大局限性。

7.刚才在MS Downloader里面下载了一些关于WCF的Samples,觉得不错。但自己对高级查询中的一些查询项还是摸不太清头脑,不晓得Product/Technology和Category这两个关键的查询选项到底应该怎么设,只要统统暂设成All。
地址:http://www.microsoft.com/downloads/advancedsearch.aspx?displaylang=en

8.看了一个关于MessageContract的最简单的例子,就是定义一个[MessageContract]的类型,并在其中定义[MessageHeader]和[MessaegBodyMember]。然后这个类型就可以作为一个WCF服务的调用参数类型和返回参数类型了。

下班了,下周继续 ^&^


相关文章: