成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳解WCF可擴(kuò)展框架中的行為擴(kuò)展

開發(fā) 開發(fā)工具
WCF行為擴(kuò)展,給予開發(fā)人員很大的便利,本文將詳細(xì)介紹WCF行為的擴(kuò)展。

WCF以其靈活的可擴(kuò)展架構(gòu)為開發(fā)者提供了方便,其中對(duì)行為的擴(kuò)展或許是應(yīng)用中最為常見的。自定義對(duì)行為的擴(kuò)展并不復(fù)雜,但仍有許多細(xì)節(jié)需要注意。

在服務(wù)端,一般是對(duì)DispatchRuntime和DispatchOperation進(jìn)行擴(kuò)展,擴(kuò)展點(diǎn)包括了對(duì)參數(shù)和消息的檢查,以及操作調(diào)用程序, 它們對(duì)應(yīng)的接口分別為IParameterInspector,IDispatchMessageInspector以及 IOperationInvoker。而在客戶端,則是對(duì)ClientRuntime和ClientOperation進(jìn)行擴(kuò)展,擴(kuò)展點(diǎn)包括對(duì)參數(shù)和消息 的檢查,對(duì)應(yīng)的接口分別為IParameterInspector和IClientMessageInspector。這些接口類型均被定義在 System.ServiceModel.Dispatcher命名空間下,其中IParameterInspector接口可以同時(shí)作用在服務(wù)端和客戶端。

對(duì)這些接口的實(shí)現(xiàn),有點(diǎn)類似于AOP的實(shí)現(xiàn),可以對(duì)方法調(diào)用前和調(diào)用后注入一些額外的邏輯,所以通常會(huì)將這些擴(kuò)展稱為偵聽器。例如IParameterInspector接口,就定義了如下方法:

void AfterCall(string operationName, object[] outputs,

object returnValue, object correlationState);
object BeforeCall(string operationName, object[] inputs);

在調(diào)用服務(wù)對(duì)象的目標(biāo)方法前,會(huì)調(diào)用BeforeCall方法,而在調(diào)用后則會(huì)調(diào)用AfterCall方法。例如我們可在方法調(diào)用前檢驗(yàn)計(jì)算方法的參數(shù)是否小于0,如果小于0則拋出異常:

public class CalculatorParameterInspector:IParameterInspector
{
public void BeforeCall(string operationName, object[] inputs)
{
int x = inputs[0] as int;
int y = inputs[1] as int;
if (x <0 || y < 0)
{
 throw new FaultException("The number can not be less than zero.");
}
return null;
}
public void AfterCall(string operationName, object[] outputs, object returnValue,

object correlationState)
{
//empty;
}
}

對(duì)消息的檢查區(qū)分了服務(wù)端和客戶端,接口方法根據(jù)消息傳遞的順序剛好相反[注]。我們可以通過(guò)接口方法對(duì)消息進(jìn)行處理,例如打印消息的Header:

public class PrintMessageInterceptor : IDispatchMessageInspector
{
#region IDispatchMessageInspector Members

public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel, InstanceContext instanceContext)
{
MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
request = buffer.CreateMessage();

Console.WriteLine("After Receive Request:");
foreach (MessageHeader header in request.Headers)
{
Console.WriteLine(header);
}
Console.WriteLine(new string('*', 20));
return null;
}

public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue);
reply = buffer.CreateMessage();

Console.WriteLine("Before Send Request:");
foreach (MessageHeader header in reply.Headers)
{
Console.WriteLine(header);
}
Console.WriteLine(new string('*', 20));
}

#endregion


#p#

WCF提供了四種類型的行為:服務(wù)行為、終結(jié)點(diǎn)行為、契約行為和操作行為。 這四種行為分別定義了四個(gè)接口:IServiceBehavior,IEndpointBehavior,IContractBehavior以及 IOperationBehavior。雖然是四個(gè)不同的接口,但它們的接口方法卻基本相同,分別為 AddBindingParameters(),ApplyClientBehavior()以及ApplyDispatchBehavior()。注 意,IServiceBehavior由于只能作用在服務(wù)端,因此并不包含ApplyClientBehavior()方法。

我們可以定義自己的類實(shí)現(xiàn)這些接口,但需要注意幾點(diǎn):

1、行為的作用范圍,可以用如下表格表示:

2、可以利用自定義特性的方式添加擴(kuò)展的服務(wù)行為、契約行為和操作行為,但不能添加終結(jié)點(diǎn)行為;可以利用配置文件添加擴(kuò)展服務(wù)行為和終結(jié)點(diǎn)行為,但不能添加契約行為和操作行為。但這些擴(kuò)展的行為都可以通過(guò)ServiceDescription添加。

利用特性添加行為,意味著我們?cè)诙x自己的擴(kuò)展行為時(shí),可以將其派生自Attribute類,然后以特性方式添加。例如:

[AttributeUsage(AttributeTargets.Class|AttributeTargets.Interface)]
public class MyServiceBehavior:Attribute, IServiceBehavior...
[MyServiceBehavior]
public interface IService...

如果以配置文件的方式添加行為,則必須定義一個(gè)類繼承自BehaviorExtensionElement(屬于命名空間System.ServiceModel.Configuration),然后重寫屬性BehaviorType以及 CreateBehavior()方法。BehaviorType屬性返回的是擴(kuò)展行為的類型,而CreateBehavior()方法則負(fù)責(zé)創(chuàng)建該擴(kuò)展 行為的對(duì)象實(shí)例:

public class MyBehaviorExtensionElement:BehaviorExtensionElement
{
public MyBehaviorExtensionElement() { }
public override Type BehaviorType
{
get { return typeof(MyServiceBehavior); }
}

protected override object CreateBehavior()
{
return new MyServiceBehavior();
}
}

如果配置的Element添加了新的屬性,則需要為新增的屬性應(yīng)用ConfigurationPropertyAttribute,例如:

[ConfigurationProperty("providerName",IsRequired = true)]
public virtual string ProviderName
{
get
{
return this["ProviderName"] as string;
}
set
{
this["ProviderName"] = value;
}
}

配置文件中的配置方法如下所示:





address="http://localhost:801/Calculator"
binding="basicHttpBinding"
contract="MessageInspectorDemo.ICalculator"/>
service>
services>




behavior>
serviceBehaviors>
behaviors>


 type="MessageInspectorDemo.MyBehaviorExtensionElement, MessageInspectorDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
behaviorExtensions>
extensions>
system.serviceModel>
configuration>

注意,在一節(jié)中,下的就是我們擴(kuò)展的行為,providerName則是 MyBehaviorExtensionElement增加的屬性。如果擴(kuò)展了IEndpointBehavior,則配置節(jié)的名稱為。節(jié)負(fù)責(zé)添加自定義行為的擴(kuò)展。其 中,中的name值與下 的對(duì)應(yīng)。

特別注意的是下的 type值,必須是類型的full name。第一個(gè)逗點(diǎn)前的內(nèi)容為完整的類型名(包括命名空間),第二部分為完整的命名空間。Version,Culture以及 PublicKeyToken也是缺一不可的。每個(gè)逗點(diǎn)后必須保留一個(gè)空格,否則無(wú)法正確添加擴(kuò)展行為的配置。這與反射有關(guān),但太容易讓人忽略這一小細(xì)節(jié)。希望微軟能在后來(lái)的版本中修訂這個(gè)瑕疵。

 3、在行為擴(kuò)展的適當(dāng)方法中,需要添加參數(shù)檢查、消息檢查或操作調(diào)用程序的擴(kuò)展。這之間存在一定的對(duì)應(yīng)關(guān)系。對(duì)于參數(shù)檢查,我們需要在IOperationBehavior接口類型中的ApplyClientBehavior()以及ApplyDispatchBehavior()中添加。例如對(duì)于之前的CalculatorParameterInspector,我們可以定義一個(gè)類CalculatorParameterValidation:

public class CalculatorParameterValidation:Attribute, IOperationBehavior
{
#region IOperationBehavior Members
public void AddBindingParameters(OperationDescription operationDescription,
BindingParameterCollection bindingParameters)
{
}

public void ApplyClientBehavior(OperationDescription operationDescription,
ClientOperation clientOperation)
{
CalculatorParameterInspector inspector = new CalculatorParameterInspector();
clientOperation.ParameterInspectors.Add(inspector);
}

public void ApplyDispatchBehavior(OperationDescription operationDescription,
DispatchOperation dispatchOperation)
{
CalculatorParameterInspector inspector = new CalculatorParameterInspector();
dispatchOperation.ParameterInspectors.Add(inspector);
}

public void Validate(OperationDescription operationDescription)
{
}
#endregion
}

如果檢查器與擴(kuò)展行為在職責(zé)上沒有分離的必要,一個(gè)更好的方法是定義一個(gè)類同時(shí)實(shí)現(xiàn)IParameterInspector和IOperationBehavior接口,例如:

public class CalculatorParameterValidation:Attribute, IParameterInspector, IOperationBehavior
{
#region IParameterInspector Members
public void BeforeCall(string operationName, object[] inputs)
{
int x = inputs[0] as int;
int y = inputs[1] as int;
if (x <0 || y < 0)
{
 throw new FaultException("The number can not be less than zero.");
}
return null;
}
public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
{
//empty;
}
#endregion

#region IOperationBehavior Members
public void AddBindingParameters(OperationDescription operationDescription,
BindingParameterCollection bindingParameters)
{
}

public void ApplyClientBehavior(OperationDescription operationDescription,
ClientOperation clientOperation)
{
CalculatorParameterInspector inspector = new CalculatorParameterInspector();
clientOperation.ParameterInspectors.Add(thisinspector);
}

public void ApplyDispatchBehavior(OperationDescription operationDescription,
DispatchOperation dispatchOperation)
{
CalculatorParameterInspector inspector = new CalculatorParameterInspector();
dispatchOperation.ParameterInspectors.Add(thisinspector);
}

public void Validate(OperationDescription operationDescription)
{
}
#endregion
}

操作調(diào)用程序雖然通過(guò)IOperationBehavior進(jìn)行關(guān)聯(lián),但確是通過(guò)DispatchOperation的Invoker屬性。假定我們已經(jīng)定義了一個(gè)實(shí)現(xiàn)IOperationInvoker的類MyOperationInvoker,則關(guān)聯(lián)的方法為:

public class MyOperationInvokerBehavior : Attribute, IOperationBehavior
{
#region IOperationBehavior Members
public void AddBindingParameters(OperationDescription operationDescription,
BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(OperationDescription operationDescription,
ClientOperation clientOperation)
{
}
public void ApplyDispatchBehavior(OperationDescription operationDescription,
DispatchOperation dispatchOperation)
{
dispatchOperation.Invoker = new MyOperationInvoker(dispatchOperation.Invoker);
}
public void Validate(OperationDescription operationDescription)
{
}
#endregion
}

#p#

至于對(duì)Dispatch的消息檢查,則可以通過(guò)IServiceBehavior,IEndpointBehavior或 IContractBehavior中DispatchRuntime的MessageInspectors添加;而對(duì)Client的消息檢查則可以通過(guò) IEndpointBehavior或IContractBehavior中ClientRuntime的MessageInspectors添加(注意,此時(shí)與IServiceBehavior無(wú)關(guān),因?yàn)樗粫?huì)作用于客戶端代理)。例如:

 public class PrintMessageInspectorBehavior : IDispatchMessageInspector,IEndpointBehavior
{
//略去IDispatchMessageInspector接口成員的實(shí)現(xiàn);

#region IEndpointBehavior Members
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
//empty;
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(this);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);
}
public void Validate(ServiceEndpoint endpoint)
{
//empty;
}
#endregion
}
如果實(shí)現(xiàn)的是IServiceBehavior接口,則需要遍歷ApplyDispatchBehavior()方法中的ServiceHostBase對(duì)象:

public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
{
foreach (EndpointDispatcher endpointDispatcher in channelDispatcher .Endpoints)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);
}
}
}

注:IDispatchMessageInspector 接口的方法為BeforeSendReply()和AfterReceiveRequest();而IClientMessageInspector接口 的方法則為BeforeSendRequest()和AfterReceiveReply()。

【編輯推薦】

  1. WCF中通過(guò)Dispose有效實(shí)現(xiàn)重用
  2. WCF從理論到實(shí)踐(16):操作重載(帶視頻+ppt+源碼)
  3. 承載和使用WCF服務(wù)
責(zé)任編輯:彭凡 來(lái)源: IT168
相關(guān)推薦

2009-11-06 14:08:06

WCF行為擴(kuò)展

2010-07-02 09:25:37

.NET 4.0可擴(kuò)展

2010-02-26 10:46:12

WCF行為擴(kuò)展

2010-02-26 15:07:20

WCF單例服務(wù)

2010-03-01 14:41:14

WCF行為擴(kuò)展

2016-01-31 17:45:31

2009-09-21 16:59:29

Array擴(kuò)展

2010-03-30 08:40:36

WCF

2023-12-12 08:00:00

2020-08-18 08:04:16

DubboSPI框架

2022-06-16 08:00:00

元數(shù)據(jù)數(shù)據(jù)中心數(shù)據(jù)架構(gòu)

2024-10-10 14:01:34

2021-05-17 07:28:23

Spring可擴(kuò)展性項(xiàng)目

2022-04-15 09:59:08

Lexical開源Meta

2017-12-17 16:49:37

對(duì)象設(shè)計(jì)數(shù)據(jù)行為擴(kuò)展

2010-01-12 09:10:31

Java EE 6Servlet 3.0Web分片

2024-02-19 10:23:10

系統(tǒng)研究

2014-07-11 09:33:24

iOS 8動(dòng)作擴(kuò)展

2009-11-05 15:18:19

WCF擴(kuò)展

2022-07-01 13:08:58

編輯器框架
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 精品国产免费人成在线观看 | 国产精品一区三区 | 亚洲精品一区二区三区在线 | 亚洲欧美一区二区三区视频 | 成人国产精品入口免费视频 | 免费在线观看成人 | 日韩在线观看视频一区 | 一区免费 | 成人性生交大片免费看中文带字幕 | 日韩在线免费视频 | 91午夜在线 | 99久久99热这里只有精品 | 粉嫩av久久一区二区三区 | 九九热精 | 日本精品999 | 国产永久免费 | 国产精品一区二区久久久久 | 国产一区二区在线免费 | 国产精品国产三级国产aⅴ中文 | 成人av在线播放 | 亚洲人成在线观看 | 日韩精品成人av | 国产日韩欧美激情 | a在线视频观看 | 日韩在线一区二区三区 | 91精品国产91久久久久福利 | 九九综合 | 久久久精品网 | av在线播放一区二区 | 国产精品一区二 | 精品无码久久久久久久动漫 | 久久不卡 | 免费视频一区二区 | 亚洲免费三级 | 精品国产91亚洲一区二区三区www | 久久久久午夜 | 无人区国产成人久久三区 | 亚洲精品一区二区三区蜜桃久 | 欧美日韩午夜精品 | 盗摄精品av一区二区三区 | 精品国产91乱码一区二区三区 |