WCF(6)サービス契約の詳細な分析の[次]

I.はじめに

   以前のブログ記事では、我々はWCFに重い負荷を動作させるためにどのように分析され、主なポイントは同じではありませんでしたが、クライアントが経由で操作を行うためのオペレータのエイリアスを定義するには、サーバーのServiceContract Nameプロパティによって達成されますクライアントプロキシクラスを達成する方法を書き換えます。シェア継承契約は、このブログ記事で実装されます。

第二に、WCFサービス契約の制限の実装を継承します

   まず、契約の継承を達成するためのWCF伝統的な方法の下で、の場合は、単純なWCFアプリケーションによって継承された契約のいずれかの変更を加えることなく達成されたかを見てみましょう。我々はまだこのWCFアプリケーションを達成するために、前の手順に従ってください。

  • ステップ1:実装WCFサービス

   ここで、我々は2件のサービス契約を定義し、それらの間の関係の継承は、特定の実装コードは次のとおりです。

サービス契約// 1
2〔のServiceContract]
3 ISimpleInstrumentationパブリックインターフェース。
4 {
5 [OperationContract]。
6 WriteEventLog文字列();
7}
8。
9 //サービス契約、サービス契約がISimpleInstrumentation継承。
10 [のServiceContract]を
11パブリックインターフェイスICompleteInstrumentation:ISimpleInstrumentation。
{12は
13れる[OperationContract]
14 IncreatePerformanceCounterストリング();
15}

  その上ICompleteInstrumentationはISimpleInstrumentationを継承したサービス契約、ように2つのインタフェースを定義します。それ継承プロパティの上にAttributeUsageは、インターフェイスの継承を導出することはできませんServiceContractAttributeに代わって、falseに設定されているため、ICompleteInstrumentationはISimpleteInstrumentationから継承されますが、しかし、ServiceContractAttribute継承されていないICompleteInstrumentationでISimpleInstrumentationで使用:これは、ことに留意すべきです。次のようにServiceContractAttribute具体的な定義は以下のとおりです。

| [AttributeUsageAttribute(AttributeTargets.Class = falseを、継承AttributeTargets.Interface、
AllowMultiple =偽)]
属性:公共密封されたクラスServiceContractAttribute

  次に、以下のように対応するサービスの特定の実装コードを達成するために:

//实现ISimpleInstrumentation契约
パブリッククラスSimpleInstrumentationService:ISimpleInstrumentation
{
#regionのISimpleInstrumentationメンバー
パブリック文字列WriteEventLog()
{
リターン"シンプル計装サービスが呼び出されます";
}
#endregion
}

//实现ICompleteInstrumentation契约
パブリッククラスCompleteInstrumentationService:SimpleInstrumentationService、ICompleteInstrumentation
{
公共の文字列IncreatePerformanceCounterは、()
{
リターンが"Increateパフォーマンスカウンタが呼び出されます";
}
}

  上記、コードを再利用するために、CompleteInstrumentationServiceことによりメソッドWriteEventLogを再定義する必要がなくなり、SimpleInstrumentationServiceから継承されました。

  • ステップ2:サービスホストを実装

   サービスの完了は、今のサービスのホストを達成するために見て、定義された次のようにサービスホストは、コンソールアプリケーション、特定の実装コードと同様の前の章、特定の実装コードのコードですされた後:

//サービスホスト1、ホストコンソールWCFサービスプログラムを実装
2プログラムクラスを
3 {
4静的な無効メイン(文字列[] args)
5 {
6 =のServiceHost新しい新しいホスト(使用のServiceHost(typeof演算(WCFService.CompleteInstrumentationService)) )
7。{
8 host.Opened + =デリゲート。
9 {
10 Console.WriteLineを( "スタート・サービス");
11};
12である
13が開いている通信チャネル//
14 host.Open();
15 Console.Read();
16}
17
18}
19}

  次のようにホストプログラムに対応するプロファイル情報は以下のとおりです。

<構成>
<system.serviceModel>
<行動>
<serviceBehaviors>
<行動名= "metadataBehavior">
<httpGetEnabled serviceMetadata = "trueに" />
</行動>
</ serviceBehaviors>
</行動>
<サービス>
<! -名前プロパティサービスラベル形式を指定し、必要であり、サービスタイプとして指定する必要があります。名前空間サービスクラス名- >
< -詳しくはMSDNを参照することができます!のhttp://msdn.microsoft.com/zh -CN /ライブラリ/ ms731303(V = vs.110)の.aspx - >
< -サービス名= "WCFService.CompleteInstrumentationService" behaviorConfiguration = "metadataBehavior">
<エンドポイントアドレス= "MEX"バインディング= "mexHttpBinding"契約=「WCFService。 ICompleteInstrumentation「/>
<ホスト>
<baseAddresses>
<追加BASEADDRESS = "のhttp:// localhostを:9003 / instrumentationService /" />
</ baseAddresses>
</ホスト>
</サービス>
</サービス>
</system.serviceModel>
</ configuration>の

  • ステップ3:クライアントの実装

   最後に、それはここでは、サービスにアクセスするために我々のクライアントを実現する最初の管理者権限を持つWCFServiceHostByConsoleApp.exeが実行可能な実行するホストアプリケーションに管理者権限で実行することです。以下に示すように、正常実行した後は、特定のオペレーティング結果、コンソールでサービスのスタートアップの成功メッセージが表示されます。

  します。http:// localhost:9003 / instrumentationService /オーダー、サービス参照の追加]ウィンドウのアドレスを入力するように続いてサービス参照を追加するためにサービス参照を追加する方法により、クライアントは、それは忘れてはならない。この時、まず、ホスティングサービスを実行する必要がありますメタデータ情報サービスを取得します。以前に加えた後に正常に追加され、svcutil.exeツールは、私たちのために、対応するクライアントプロキシクラスを生成するだけでなく、自動的にプロファイル情報を追加するだけでなく、私たちのために参照System.ServiceModel.dllを追加します。ここに私たちのツールは、コードを生成します:

[System.CodeDom.Compiler.GeneratedCodeAttribute( "System.ServiceModel"、 "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName = "ServiceReference.ICompleteInstrumentation")]
パブリックインターフェイスICompleteInstrumentation {

[System.ServiceModel.OperationContractAttribute(アクション= "http://tempuri.org/ISimpleInstrumentation/WriteEventLog"、ReplyAction = "http://tempuri.org/ISimpleInstrumentation/WriteEventLogResponse")]
列WriteEventLog()。

[System.ServiceModel.OperationContractAttribute(ACTION = "http://tempuri.org/ISimpleInstrumentation/WriteEventLog"、ReplyAction = "http://tempuri.org/ISimpleInstrumentation/WriteEventLogResponse")]
System.Threading.Tasks.Task <ストリング>

[System.ServiceModel.OperationContractAttribute(ACTION = "http://tempuri.org/ICompleteInstrumentation/IncreatePerformanceCounter"、ReplyAction = "http://tempuri.org/ICompleteInstrumentation/IncreatePerformanceCounterResponse")]
列IncreatePerformanceCounter()。

[System.ServiceModel.OperationContractAttribute(ACTION = "http://tempuri.org/ICompleteInstrumentation/IncreatePerformanceCounter"、ReplyAction = "http://tempuri.org/ICompleteInstrumentation/IncreatePerformanceCounterResponse")]
System.Threading.Tasks.Task <ストリング> IncreatePerformanceCounterAsync();
}

[System.CodeDom.Compiler.GeneratedCodeAttribute( "System.ServiceModel"、 "4.0.0.0")]
パブリックインターフェイスICompleteInstrumentationChannel:ClientConsoleApp.ServiceReference.ICompleteInstrumentation、System.ServiceModel.IClientChannel {
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute( "System.ServiceModel"、 "4.0.0.0")]
パブリック部分クラスCompleteInstrumentationClient:System.ServiceModel.ClientBase <ClientConsoleApp.ServiceReference.ICompleteInstrumentation>、ClientConsoleApp.ServiceReference.ICompleteInstrumentation {

パブリックCompleteInstrumentationClient(){
}

公共CompleteInstrumentationClient(文字列endpointConfigurationName):
塩基(endpointConfigurationName){
}

公共CompleteInstrumentationClient(文字列endpointConfigurationName、文字列[リモート):
ベース(endpointConfigurationName、[リモート){
}

公共CompleteInstrumentationClient(文字列endpointConfigurationName、System.ServiceModel.EndpointAddress [リモート):
ベース(endpointConfigurationName、[リモート){
}

公共CompleteInstrumentationClient(System.ServiceModel.Channels.Binding )、System.ServiceModel.EndpointAddress [リモート結合:
塩基(結合、[リモート){
}

パブリック文字列WriteEventLog(){
(base.Channel.WriteEventLogを返します)。
}

公共System.Threading.Tasks.Task <ストリング> WriteEventLogAsync(){
)(base.Channel.WriteEventLogAsyncを返します。
}

パブリック文字列IncreatePerformanceCounter(){
base.Channel.IncreatePerformanceCounter()を返します。
}

公共System.Threading.Tasks.Task <ストリング> IncreatePerformanceCounterAsync(){
)(base.Channel.IncreatePerformanceCounterAsyncを返します。
}
}

  サービス側では、我々は、サービス契約の継承階層を定義し、エンドポイントがICompleteInstrumentation契約で開示しています。しかし、クライアントは、我々は、生成されたサービス契約の方法により、サービス参照を追加しますが、継承関係は、クライアントプロキシクラスが唯一のサービス契約を定義する場合には赤いマークが付いたコード、上記の場所で見ることができませんサービス契約は、操作のすべてを定義します。このとき、クライアントの実装コードを以下に示します。

1クラスプログラム
2 {
3静的な無効メイン(文字列[] args)
4 {
5 Console.WriteLineを( "WCFサービスのメソッドを呼び出すVSツールによって---使用Genergateクライアント---")。
6使用(CompleteInstrumentationClientプロキシ=新しいCompleteInstrumentationClient())
7 {
8 Console.WriteLineを(proxy.WriteEventLog())。
9 Console.WriteLineを(proxy.IncreatePerformanceCounter())。
10}
11
12 Console.Read()。
13}
14}

  上記のコードからわかるように。私たちは今、サービスを呼び出すが、CompleteInstrumentationClientプロキシクラスを呼び出すことによって行われ、私たちは、クライアントプロキシクラスの継承構造はまた、契約関係を持っていることを期待することができます。

第三に、クライアントの契約レベルを達成するために

   さて、自動生成されたコードは、その後、私たちは、カスタムの方法により、独自のプロキシクラスを定義することができ、我々のニーズを完了することはできません。

  • 最初のステップは、クライアントのサービス契約を定義することです。特定のカスタムコードは次のとおりです。

ClientConsoleApp名前空間1。
2 {
継承の結果としてそれを維持するサーバと3 //カスタムサービスコントラクト。
4【のServiceContract]。
5 ISimpleInstrumentationパブリックインターフェイス。
6 {
7 [OperationContract]。
8 WriteEventLogストリング();。
。9}
10
11 [のServiceContract]。
パブリックインターフェイスICompleteInstrumentation 12は:ISimpleInstrumentation
13 {である
14 [OperationContract]
15 IncreatePerformanceCounterストリング();
16}
17}。

  • ステップ2:カスタム2つのプロキシクラス、特定の実装コードは次のよう:

//自定义代理类
パブリッククラスSimpleInstrumentationClient:ClientBase <ICompleteInstrumentation>、ISimpleInstrumentation
{
#region ISimpleInstrumentation人が
公共の文字列WriteEventLog()
{
)(this.Channel.WriteEventLogを返します。
}
#endregion
}

パブリッククラスCompleteInstrumentationClient:SimpleInstrumentationClient、ICompleteInstrumentation
{
パブリック文字列IncreatePerformanceCounter()
{
)(this.Channel.IncreatePerformanceCounterを返します。
}
}

  以下の修正に対応する設定ファイル:

<設定>
<system.serviceModel>
<バインディング>
<wsHttpBinding>
<バインディング名= "MetadataExchangeHttpBinding_ICompleteInstrumentation1">
<セキュリティモード= "なし" />
</結合>
</ wsHttpBinding>
</バインディング>
<クライアント>
<エンドポイントアドレス= "のhttp:// localhostを:9003 / instrumentationService / MEX"
バインディング= "wsHttpBinding" bindingConfiguration = "MetadataExchangeHttpBinding_ICompleteInstrumentation1"
契約= "ClientConsoleApp.ICompleteInstrumentation"名前= "MetadataExchangeHttpBinding_ICompleteInstrumentation1" />
</クライアント>
</system.serviceModel>
</設定>

  • 第三段階:クライアント・サービス・コールを実施するために、プロキシクラスから今回は、それぞれ次のように2つの特定の実装コードによる操作を呼び出す2つのサービス契約に対応するように定義することができます。

1クラスプログラム
2 {
3静的な無効メイン(文字列[] args)
4 {
5を用いて(SimpleInstrumentationClient PROXY1 =新しいSimpleInstrumentationClient())
6 {
7 Console.WriteLineを(proxy1.WriteEventLog())。
8}
9を用いて(CompleteInstrumentationClient PROXY2 =新しいCompleteInstrumentationClient())
10 {
11 Console.WriteLineを(proxy2.IncreatePerformanceCounter())。
12}
13
14 Console.Read()。
15}
16}

  このように、プロキシクラスを書き換える方法により、クライアントは完全にサービス契約のメソッドを呼び出すためのアプローチをオブジェクト指向することができ、具体的な運用結果は以下に示すように:

  あなたは2つのプロキシクラスを定義したくない場合にも、あなたはまた、次のようにサービス契約のための具体的な実装手順を呼び出すことができます。

  • 最初のステップ:同じことは以前のようにサービス契約の継承、特定の実装コードを用いて達成されます。

//継承の結果としてそれを維持するサーバとカスタムサービス契約
【のServiceContract]
パブリックインターフェイスISimpleInstrumentation
{
[OperationContract]
ストリングWriteEventLog();
}

[のServiceContract]
パブリックインターフェイスICompleteInstrumentation:ISimpleInstrumentation
{
[OperationContract]
ストリングIncreatePerformanceCounter()。
}

  • ステップ2:設定ファイルを変更します。次のようにクライアントのプロファイルが変更されます。

<設定>
<system.serviceModel>
<クライアント>
<エンドポイントアドレス= "のhttp:// localhostを:9003 / instrumentationService / MEX"
バインディング= "mexHttpBinding"契約= "ClientConsoleApp.ISimpleInstrumentation"
名前= "ISimpleInstrumentation" />
<エンドポイントアドレス= "のhttp:// localhostを:9003 / instrumentationService / MEX"
バインディング= "mexHttpBinding"契約= "ClientConsoleApp.ICompleteInstrumentation"
名前= "ICompleteInstrumentation" />
</クライアント>
</system.serviceModel>
</ configuration>の

  • 第三段階:クライアントコードの実装。特定の実装コードを以下に示します。

1クラスプログラム
2 {
3静的な無効メイン(文字列[] args)
4 {
5を用いて(のChannelFactory <ISimpleInstrumentation> simpleChannelFactory =新規のChannelFactory <ISimpleInstrumentation>( "ISimpleInstrumentation"))
6 {
7 ISimpleInstrumentation simpleProxy = simpleChannelFactory.CreateChannel()。
8(simpleProxy IDisposableインターように)を使用して
9 {
10 Console.WriteLineを(simpleProxy.WriteEventLog())。
11}
12}
13使用(のChannelFactory <ICompleteInstrumentation> completeChannelFactor =新規のChannelFactory <ICompleteInstrumentation>( "ICompleteInstrumentation"))
14 {
15 ICompleteInstrumentation completeProxy = completeChannelFactor.CreateChannel()。
16(completeProxy IDisposableインターように)を用いて
17 {
18 Console.WriteLineを(completeProxy.IncreatePerformanceCounter())。
19}
20}
21
22 Console.Read()。
23}
24}

  実際には、上記の原則と実装コードは、コードの実装を呼び出すクライアントにプロキシクラスを2つのクライアントプロキシクラスが同じで定義しますが、この時間。上記のコードによって分かるように、主にサーバとの通信チャネルを作成するために、通信する、すなわちチャネル、CreateChannel方法、およびプロキシクラスを定義することによってのChannelFactory <T>を介して通信チャネルを作成するために、上記直接はClientBaseを介してです<T>チャネル特性の自体もChannelFactory.CreateChannel法によってチャネルを作成し、作成した外部チャネル取得のために、プロパティチャンネルに作成したチャンネルを割り当てるClientBaseクラスを実装し、現在の通信チャネルを、得ることができます。だから、2つの実装の原理は同じで、自動的に生成されたプロキシクラスで同じ原理です。

IVの概要

  ここでは、この記事の共有の内容は以上、本論文では、カスタムエージェントクラスによって継承されたサービス契約のために呼び出すことです。ヘビーデューティー操作上のその実装のアイデアとアイデアの実現には、クライアントコードが自動的に生成されたクラスは、需要を満たすことができないので、それが唯一のカスタムを拡張します、同じです。ブログの記事は、WCFでデータコントラクトを共有するために続けて後ろにこの共有サービス契約は、最後に来ます。

 

転送します。https://www.cnblogs.com/zhili/p/MSMQ.html、著者:ハード学びます。

侵害した場合、削除するために私に連絡してください!

おすすめ

転載: blog.csdn.net/IT_0802/article/details/91501851