WCF是.NET平台下实现SOA的一种手段,SOA的一个重要的特征就基于Message的通信方式。从Messaging的角度讲,WCF可以看成是对Message进行发送、传递、接收、基础的工具。对于一个消息交换的过程,很多人只会关注message的最初的发送端和最终的接收端。实际上在很多情况下,在两者之间还存在很多的中间结点(Intermediary),这些中间结点在可能在实际的应用中发挥中重要的作用。比如,我们可以创建路由器(Router)进行消息的转发,甚至是Load Balance;可以创建一个消息拦截器(Interceptor)获取request或者response message,并进行Audit、Logging和Instrumentation。今天我们就我们的目光转向这些充当着中间人角色的Intermediary上面来。
在本篇文章中,我们将会创建一个message的拦截和转发工具(message interceptor)。它将被置于WCF调用的client和service之间,拦截并转发从client到service的request message,以及service到client的response message,并将request message和response message显示到一个可视化的界面上。我们将讨论这个message interceptor若干种不同的实现方式。
有一点需要明确说明的是,这个工具的创建并非我写作这篇文章的目的,我的目的是通过一个具体的例子让大家以一种直观方式对WCF的Addressing机制有一个深刻的认识。在介绍message interceptor的创建过程中,我会穿插介绍一个WCF的其它相关知识,比如Message Filtering、Operation Selection、Must Understand Validation等等。
一、创建一个简单的WCF应用
由于我们将要创建的message interceptor需要应用到具体的WCF应用中进行工作和检验,我们需要首先创建一个简单的WCF应用。我们创建一个简单的Calculation的例子。这个solution采用我们熟悉的四层结构(Interceptor用于host我们的message intercept service):
1、Contract:Artech.MessageInterceptor.Contracts.ICalculate
1: using System.ServiceModel;<!--CRLF-->
2: namespace Artech.MessageInterceptor.Contracts<!--CRLF-->
3: { <!--CRLF-->
4: [ServiceContract] <!--CRLF-->
5: public interface ICalculate<!--CRLF-->
6: { <!--CRLF-->
7: [OperationContract] <!--CRLF-->
8: double Add(double x, double y);<!--CRLF-->
9: } <!--CRLF-->
10: } <!--CRLF-->
2、Service:Artech.MessageInterceptor.Services.CalculateService
1: using Artech.MessageInterceptor.Contracts;<!--CRLF-->
2: namespace Artech.MessageInterceptor.Services<!--CRLF-->
3: { <!--CRLF-->
4: public class CalculateService : ICalculate<!--CRLF-->
5: { <!--CRLF-->
6: #region ICalculate Members<!--CRLF-->
7: <!--CRLF-->
8: public double Add(double x, double y)<!--CRLF-->
9: { <!--CRLF-->
10: return x + y;<!--CRLF-->
11: } <!--CRLF-->
12: <!--CRLF-->
13: #endregion<!--CRLF-->
14: } <!--CRLF-->
15: } <!--CRLF-->
16: <!--CRLF-->
3、Hosting:Artech.MessageInterceptor.Hosting.Program
1: using System;<!--CRLF-->
2: using System.ServiceModel;<!--CRLF-->
3: using Artech.MessageInterceptor.Services;<!--CRLF-->
4: namespace Artech.MessageInterceptor.Hosting<!--CRLF-->
5: { <!--CRLF-->
6: class Program<!--CRLF-->
7: { <!--CRLF-->
8: static void Main(string[] args)<!--CRLF-->
9: { <!--CRLF-->
10: using (ServiceHost host = new ServiceHost(typeof(CalculateService)))<!--CRLF-->
11: { <!--CRLF-->
12: host.Opened += delegate<!--CRLF-->
13: { <!--CRLF-->
14: Console.WriteLine("The calculate service has been started up!");<!--CRLF-->
15: }; <!--CRLF-->
16: host.Open(); <!--CRLF-->
17: Console.Read(); <!--CRLF-->
18: } <!--CRLF-->
19: } <!--CRLF-->
20: } <!--CRLF-->
21: } <!--CRLF-->
22: <!--CRLF-->
Configuration
1: <?xml version="1.0" encoding="utf-8" ?><!--CRLF-->
2: <configuration><!--CRLF-->
3: <system.serviceModel><!--CRLF-->
4: <bindings><!--CRLF-->
5: <customBinding><!--CRLF-->
6: <binding name="MyCustomeBinding"><!--CRLF-->
7: <textMessageEncoding /><!--CRLF-->
8: <httpTransport /><!--CRLF-->
9: </binding><!--CRLF-->
10: </customBinding><!--CRLF-->
11: </bindings><!--CRLF-->
12: <services><!--CRLF-->
13: <service name="Artech.MessageInterceptor.Services.CalculateService"><!--CRLF-->
14: <endpoint binding="customBinding" bindingConfiguration="MyCustomeBinding"<!--CRLF-->
15: contract="Artech.MessageInterceptor.Contracts.ICalculate"<!--CRLF-->
16: address="http://127.0.0.1:9999/calculateservice"/><!--CRLF-->
17: </service><!--CRLF-->
18: </services><!--CRLF-->
19: </system.serviceModel><!--CRLF-->
20: </configuration><!--CRLF-->
在host我们的calculateservice的时候,我们使用了抛弃了系统定义的binding,而采用一个custom binding。是因为custom binding基于更好的可扩展能力,以利于我们后续的介绍。为了简单起见,我们仅仅需要bing为了提供最基本的功能:传输与编码,为此我仅仅添加了两个binding element:textMessageEncoding 和httpTransport。我们将在后面部分应用其他的功能,比如WS-Security.
4、Client:Artech.MessageInterceptor.Clients.Program
1: using System;<!--CRLF-->
2: using System.ServiceModel;<!--CRLF-->
3: using Artech.MessageInterceptor.Contracts;<!--CRLF-->
4: namespace Artech.MessageInterceptor.Clients<!--CRLF-->
5: { <!--CRLF-->
6: class Program<!--CRLF-->
7: { <!--CRLF-->
8: static void Main(string[] args)<!--CRLF-->
9: { <!--CRLF-->
10: using (ChannelFactory<ICalculate> channelFactory = new ChannelFactory<ICalculate>("calculateservice"))<!--CRLF-->
11: { <!--CRLF-->
12: ICalculate calculator = channelFactory.CreateChannel(); <!--CRLF-->
13: using (calculator as IDisposable)<!--CRLF-->
14: { <!--CRLF-->
15: Console.WriteLine("x + y = {2} where x = {0} ans y = {1}", 1, 2, calculator.Add(1, 2));<!--CRLF-->
16: } <!--CRLF-->
17: } <!--CRLF-->
18: <!--CRLF-->
19: Console.Read(); <!--CRLF-->
20: } <!--CRLF-->
21: } <!--CRLF-->
22: } <!--CRLF-->
23: <!--CRLF-->
Configuration:
1: <?xml version="1.0" encoding="utf-8" ?><!--CRLF-->
2: <configuration><!--CRLF-->
3: <system.serviceModel><!--CRLF-->
4: <bindings><!--CRLF-->
5: <customBinding><!--CRLF-->
6: <binding name="MyCustomBinding"><!--CRLF-->
7: <textMessageEncoding /><!--CRLF-->
8: <httpTransport /><!--CRLF-->
9: </binding><!--CRLF-->
10: </customBinding><!--CRLF-->
本文介绍如何在WCF应用中创建消息拦截器,通过具体实例深入探讨WCF的Addressing机制,同时涵盖MessageFiltering、OperationSelection等知识点。


被折叠的 条评论
为什么被折叠?



