WCF扩展系列 - 行为扩展(Behaviors)
原文地址:http://www.cnblogs.com/Creator/archive/2011/05/21/2052687.html
这个系列的第一部分将会重点关注WCF行为(behaviors),WCF提供了四种类型的行为:服务行为、终结点行为、契约行为和操作行为。这些行为的接口几乎是所有WCF的扩展入口。本篇文章只是对行为拓展讲述一些基础的铺设,具体到上面四个行为的扩展以及使用案例,将会在后续的文章中讲到.
Behaviors
上述这四个行为的所定义的接口分别是IServiceBehavior,IEndpointBehavior,IContractBehavior以及 IOperationBehavior。虽然是四个不同的接口,但它们的接口方法却基本相同,分别为 AddBindingParameters(),ApplyClientBehavior()以及ApplyDispatchBehavior()。注意,IServiceBehavior由于只能作用在服务端,因此并不包含ApplyClientBehavior()方法。
public interface I[Service/Endpoint/Contract/Operation]Behavior {
void Validate(DescriptionObject);
void AddBindingParameters(DescriptionObject, BindingParameterCollection);
void ApplyDispatchBehavior(DescriptionObject, RuntimeObject);
void ApplyClientBehavior(DescriptionObject, RuntimeObject); // not on IServiceBehavior
}
其中的方法描述如下:
- AddBindingParameters:用于向绑定元素传递自定义数据,以支持协定实现。
- Validate:用于检查服务宿主和服务说明,从而确定服务是否可成功运行。
- Apply[Client/Dispatch]Behavior:这是我们可以引用和修改WCF运行时对象的地方,也是用得最多的行为方法(大部分情况,上两个方法都会留空)。用于更改运行时属性值或插入自定义扩展对象(例如错误处理程序、消息或参数拦截器、安全扩展以及其他自定义扩展对象)。
他们各自的作用范围如下图所示(引用自张逸):

增加一个行为(behaviors )
向WCF中增加行为有三种不同的方法:
代码:service / endpoint / contract / operation 的描述类有一个behaviors集合属性,我们可以通过他简单的增加一个行为,具体做法,先将自定义服务行为添加到 Behaviors 属性,然后对 System.ServiceModel.ServiceHost 对象调用 ICommunicationObject.Open 方法。
配置文件:通过配置文件system.serviceModel/behaviors节点,我们可以指定service behaviors 和 endpoint behaviors,已达到添加行为的目的
特性: 添加行为的简单方法是使用特性 — — 除了终结点行为。通过创建特性类 (基类型 = = System.Attribute) 和实现其中一个行为接口,您可以将特性应用于适当的元素,并添加行为到元素的描述。下面的代码显示了一个简单的服务,基于特性的行为的添加以及输出它们的调用顺序 (以及通过代码添加终结点行为)。
using System;
using System.Collections.ObjectModel;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher; namespace Behaviors
{
class MyServiceBehaviorAttribute : Attribute, IServiceBehavior
{
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
Console.WriteLine("Inside {0}.{1}", this.GetType().Name, MethodBase.GetCurrentMethod().Name);
} public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
Console.WriteLine("Inside {0}.{1}", this.GetType().Name, MethodBase.GetCurrentMethod().Name);
} public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
Console.WriteLine("Inside {0}.{1}", this.GetType().Name, MethodBase.GetCurrentMethod().Name);
}
} class MyEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
Console.WriteLine("Inside {0}.{1}, endpoint {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, endpoint.Name);
} public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
Console.WriteLine("Inside {0}.{1}, endpoint {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, endpoint.Name);
} public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
Console.WriteLine("Inside {0}.{1}, endpoint {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, endpoint.Name);
} public void Validate(ServiceEndpoint endpoint)
{
Console.WriteLine("Inside {0}.{1}, endpoint {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, endpoint.Name);
}
} class MyContractBehaviorAttribute : Attribute, IContractBehavior
{
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
Console.WriteLine("Inside {0}.{1}, contract {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, contractDescription.ContractType.Name);
} public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
Console.WriteLine("Inside {0}.{1}, contract {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, contractDescription.ContractType.Name);
} public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
Console.WriteLine("Inside {0}.{1}, contract {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, contractDescription.ContractType.Name);
} public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
Console.WriteLine("Inside {0}.{1}, contract {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, contractDescription.ContractType.Name);
}
} class MyOperationBehaviorAttribute : Attribute, IOperationBehavior
{
public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
{
Console.WriteLine("Inside {0}.{1}, operation {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, operationDescription.Name);
} public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
{
Console.WriteLine("Inside {0}.{1}, operation {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, operationDescription.Name);
} public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
Console.WriteLine("Inside {0}.{1}, operation {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, operationDescription.Name);
} public void Validate(OperationDescription operationDescription)
{
Console.WriteLine("Inside {0}.{1}, operation {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, operationDescription.Name);
}
} [ServiceContract]
[MyContractBehavior]
public interface ITest
{
[OperationContract]
[MyOperationBehavior]
int Add(int x, int y);
[OperationContract]
int Multiply(int x, int y);
} [ServiceContract]
[MyContractBehavior]
public interface ITest2
{
[OperationContract]
[MyOperationBehavior]
string Echo(string text);
} [MyServiceBehavior]
public class Service : ITest, ITest2
{
public int Add(int x, int y) { return x + y; }
public int Multiply(int x, int y) { return x * y; }
public string Echo(string text) { return text; }
} class Program
{
static void Main(string[] args)
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
ServiceEndpoint ep1 = host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "basic");
ep1.Name = "Endpoint1-BasicHttp";
ep1.Behaviors.Add(new MyEndpointBehavior());
ServiceEndpoint ep2 = host.AddServiceEndpoint(typeof(ITest2), new WSHttpBinding(), "ws");
ep2.Name = "Endpoint2-WSHttp";
ep2.Behaviors.Add(new MyEndpointBehavior());
Console.WriteLine("Opening the host...");
host.Open();
Console.WriteLine("Host opened");
}
}
}
我并不认为这就是“最优”的添加方法,他只是描述通过特性增加行为的一个特定的例子而已,具体什么是“最优”的添加行为的方法呢?其实这就像软件架构一样,永远没有最好的架构,只有最合适的架构。所以具体项目里面采用哪种方式去添加来得具体情况具体分析。个人比较喜欢用使用配置文件添加的方法….
在后面的文章中将会讲诉到具体的行为扩展,敬请期待..
1.1.1. IServiceBehavior
1.1.2. IContractBehavior
1.1.3. IEndpointBehavior
1.1.4. IOperationBehavior
WCF扩展系列 - 行为扩展(Behaviors)的更多相关文章
- 【转】WCF扩展系列 - 行为扩展(Behaviors)
原文:https://www.cnblogs.com/Creator/archive/2011/05/21/2052687.html 这个系列的第一部分将会重点关注WCF行为(behaviors),W ...
- iOS开发系列--App扩展开发
概述 从iOS 8 开始Apple引入了扩展(Extension)用于增强系统应用服务和应用之间的交互.它的出现让自定义键盘.系统分享集成等这些依靠系统服务的开发变成了可能.WWDC 2016上众多更 ...
- 「译」JUnit 5 系列:扩展模型(Extension Model)
原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...
- dapper-dot-net用法及其扩展系列
dapper-dot-net用法及其扩展系列 虽然已经一段时间没写.net了,但是昨天看了下dapper和Dapper-Extensions在github仍然有更新,他们的受欢迎程度可想而知.所以想把 ...
- MVC学习系列——ModelBinder扩展
在MVC系统中,我们接受数据,运用的是ModelBinder 的技术. MVC学习系列——ActionResult扩展在这个系列中,我们自定义了XmlResult的返回结果. 那么是不是意味着能POS ...
- 浏览器扩展系列————在WPF中定制WebBrowser快捷菜单
原文:浏览器扩展系列----在WPF中定制WebBrowser快捷菜单 关于如何定制菜单可以参考codeproject上的这篇文章:http://www.codeproject.com/KB/book ...
- 浏览器扩展系列————给MSTHML添加内置脚本对象【包括自定义事件】
原文:浏览器扩展系列----给MSTHML添加内置脚本对象[包括自定义事件] 使用场合: 在程序中使用WebBrowser或相关的控件如:axWebBrowser等.打开本地的html文件时,可以在h ...
- 浏览器扩展系列————异步可插入协议(pluggable protocol)的实现
原文:浏览器扩展系列----异步可插入协议(pluggable protocol)的实现 IE中有很多我们比较熟悉的协议,如http,https,mailto,ftp等.当然你也可以实现自己定义的协议 ...
- Web应用扩展系列(1):架构篇(转)
原文:Web应用扩展系列(1):架构篇 在这篇文章中,我将尽量涵盖Web应用扩展或性能调优时可能会遇到的一些架构问题. 首先,让我们来统一一些名词或项目的概念,下文中我将列举在扩展Web应用时可能会遇 ...
随机推荐
- 我是一块cpu 《转载》
我是一块cpu,原装intel,在一台普通的台式计算机里供职.我有个小弟是内存,我要靠他时时刻刻陪伴我工作,其实有时候我并不是没有某某地址的资料,而是懒得翻--麻烦. 还有一个老大哥叫bios,每次那 ...
- TCP与UDP区别
原文链接:http://blog.sina.com.cn/s/blog_493309600100clrw.html TCP与UDP区别 TCP---传输控制协议,提供的是面向连接.可靠的字节流服务.当 ...
- oracle约束条件状态
Oracle完整性约束有一下4种: • DISABLE NOVALIDATE • ENABLE NOVALIDATE • DISABLE VALIDATE • ENABLE VALIDATE • ...
- 表单提交对chrome记住密码的影响
在处理注册.登录等含有用户名,密码的元素的表单时,chrome会主动的提示记住密码,然而这个功能在用户名的选择上真是耐人寻味,它总是寻找离password input控件最近的那一个文本框的内容,作为 ...
- c++文件读写相关
在看C++编程思想中,每个练习基本都是使用ofstream,ifstream,fstream,以前粗略知道其用法和含义,在看了几位大牛的博文后,进行整理和总结: 这里主要是讨论fstream的内容: ...
- gvim 常用命令
插入: insert 强退: :q! 退出: :q 保存: :w 保存退出::wq 复制: yy(单行) 多行:8yy 删除: dd(单行) 多行:8dd 或者 :4,8d 执行脚本: :! ...
- 转载-Linux下svn搭建配置流程
Linux下svn搭建配置流程 一. 源文件编译安装.源文件共两个,为: 1. 下载subversion源文件 subversion-1.6.1.tar.gz http://d136 ...
- 修改原代码定制bootstrap
1.下载对应的Bootstarap和node.js 注:less文件夹中包含了bootstrap中所有样式组件的less源代码: dist保存编译后的css和js等文件 2.命令行输入npm inst ...
- js事件练习--登录界面演示。
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- PHP通过链接获取二进制数据的方法
function urltoblob($url){ $data = @file_get_contents($url); //如果file得不到数据,则给空值 if(!$data){ $data = & ...