WCF-クイックガイド

WCFは、Windows CommunicationFoundationの略です。WCFの基本的な機能は、相互運用性です。これは、サービス指向アプリケーションの構築に使用されるMicrosoftの最新テクノロジの1つです。WCFは、HTTP要求が均一に表現されるメッセージベースの通信の概念に基づいており、さまざまなトランスポートメカニズムに関係なく統一されたAPIを使用できます。

WCFは、Windows Vistaの.NETフレームワークの一部として2006年に初めてリリースされ、その後数回更新されました。WCF 4.5は、現在広く使用されている最新バージョンです。

WCFアプリケーションは3つのコンポーネントで構成されています-

  • WCFサービス、
  • WCFサービスホスト、および
  • WCFサービスクライアント。

WCFプラットフォームは、サービスモデルとも呼ばれます。

WCFの基本概念

メッセージ

本体とは別のパーツで構成された通信ユニットです。メッセージインスタンスは、クライアントとサービス間のすべてのタイプの通信に対して送信および受信されます。

終点

メッセージを送信または受信するアドレスを定義します。また、メッセージのセットを定義するとともに、メッセージの送信方法を説明する通信メカニズムも指定します。エンドポイントの構造は、次の部分で構成されています-

住所

アドレスは、メッセージを受信する正確な場所を指定し、Uniform Resource Identifier(URI)として指定されます。これは、scheme:// domain [:port] / [path]として表されます。下記の住所をご覧ください−

net.tcp:// localhost:9000 / ServiceA

ここで、「net.tcp」はTCPプロトコルのスキームです。ドメインは「localhost」で、マシンまたはWebドメインの名前にすることができ、パスは「ServiceA」です。

製本

エンドポイントが通信する方法を定義します。これは、通信のインフラストラクチャを構成するいくつかのバインディング要素で構成されています。たとえば、バインディングは、TCP、HTTPなどのトランスポートに使用されるプロトコル、メッセージエンコーディングの形式、セキュリティと信頼性に関連するプロトコルを示します。

契約

これは、エンドポイントがクライアントに公開する機能を指定する操作のコレクションです。通常、インターフェイス名で構成されます。

ホスティング

WCFの観点からのホスティングとは、セルフホスティング、IISホスティング、WASホスティングなどの多くの利用可能なオプションを介して実行できるWCFサービスホスティングを指します。

メタデータ

これは、クライアントアプリケーションとWCFサービス間の簡単な対話を容易にするため、WCFの重要な概念です。通常、WCFサービスのメタデータは、有効にすると自動的に生成されます。これは、サービスとそのエンドポイントの検査によって行われます。

WCFクライアント

メソッドの形式でサービス操作を公開するために作成されるクライアントアプリケーションは、WCFクライアントと呼ばれます。これは、サービスホスティングを行うアプリケーションを含め、どのアプリケーションでもホストできます。

チャネル

チャネルは、クライアントがサービスと通信するための媒体です。さまざまなタイプのチャネルがスタックされ、チャネルスタックと呼ばれます。

石鹸

「SimpleObjectAccess Protocol」と呼ばれていますが、SOAPはトランスポートプロトコルではありません。代わりに、ヘッダーと本文のセクションで構成されるXMLドキュメントです。

WCFの利点

  • 他のサービスとの相互運用性があります。これは、クライアントとサービスの両方に.Netが必要な.NETRemotingとはまったく対照的です。

  • WCFサービスは、ASMX(Active Server Methods)Webサービスと比較して、信頼性とセキュリティを強化しています。

  • WCFでセキュリティモデルとバインディングの変更を実装する場合、コーディングを大幅に変更する必要はありません。制約を満たすために必要な構成の変更はわずかです。

  • WCFにはロギングメカニズムが組み込まれていますが、他のテクノロジーでは、必要なコーディングを行うことが不可欠です。

  • WCFは、AJAXとJSON(JavaScriptオブジェクト表記)のサポートを統合しています。

  • これは、スケーラビリティと今後のWebサービス標準のサポートを提供します。

  • 非常に堅牢なデフォルトのセキュリティメカニズムがあります。

以下にリストされているWCFとWebサービスの間にはいくつかの大きな違いがあります。

  • Attributes − WCFサービスはServiceContract属性とOperationContract属性によって定義されますが、WebサービスはWebService属性とWebMethod属性によって定義されます。

  • Protocols − WCFは、HTTP、名前付きパイプ、TCP、MSMQなどのさまざまなプロトコルをサポートしますが、WebサービスはHTTPプロトコルのみをサポートします。

  • Hosting Mechanisms − WCFホスティングには、IIS(インターネットインフォメーションサービス)、WAS(Windowsアクティベーションサービス)、セルフホスティング、Windowsサービスなど、さまざまなアクティベーションメカニズムがありますが、WebサービスはIISによってのみホストされます。

  • Services − WCFは堅牢なセキュリティ、信頼できるメッセージング、トランザクション、および相互運用性をサポートしますが、Webサービスはセキュリティサービスのみをサポートします。

  • Serializer − WCFはSystem.Runtime.Serializationを使用してDataContractシリアライザーをサポートしますが、WebサービスはSystem.Xml.Serializationを使用してXMLシリアライザーをサポートします。

  • Tools − ServiceMetadataツール(svcutil.exe)はWCFサービスのクライアント生成に使用され、WSDL.EXEツールはWebサービスのクライアント生成に使用されます。

  • Exception Handling− WCFでは、未処理の例外は、FaultContractを利用することでより適切に処理されます。これらは、SOAP障害として、Webサービスのようにクライアントに返されません。

  • Hash Table − WCFでハッシュテーブルをシリアル化することは可能ですが、Webサービスではそうではありません。

  • Bindings − WCFは、BasicHttpBinding、WSDualHttpBinding、WSHttpBindingなどのいくつかのタイプのバインディングをサポートしますが、WebサービスはSOAPまたはXMLのみをサポートします。

  • Multithreading − WCFはServiceBehaviorクラスを使用したマルチスレッドをサポートしていますが、これはWebサービスではサポートされていません。

  • Duplex Service Operations − WCFは、一方向および要求/応答サービス操作のサポートとは別に、二重サービス操作をサポートしますが、Webサービスは二重サービス操作をサポートしません。

WCFサービスアプリケーションの開発には、主にMicrosoft VisualStudioとCodePlexの2つのツールがあります。Microsoft Visual Studioは、ASP.NET Webアプリケーション、デスクトップアプリケーション、モバイルアプリケーションなど、さまざまなアプリケーションを多数開発するために必要な開発ツールの完全なパッケージです。

Microsoft Visual Studioは、.NETFramework機能を使用します。一方、CodePlexは、Microsoftのオープンソースプロジェクトホスティングサイトであり、WCFサービスアプリケーション開発用の無料ツールをいくつか提供しています。

Microsoft Visual Studio

Microsoft Visual Studioには多くのエディションがあり、当初は(Visual Studio 2005)はWCF開発の熱心な支持者ではありませんでした。現在、Visual Studio 2008は、WCFサービスアプリケーションの開発に使用できる唯一のMicrosoftIDEです。

現在、Microsoft Visual Studio 2010の最新バージョンは、WCFサービスアプリケーションを開発するための推奨ツールでもあります。Visual Studioには、WCFサービスアプリケーションを開発するための既製のテンプレートもあります。

このようなテンプレートを選択すると、次の目的でファイルが追加されます-

  • サービス契約
  • サービスの実装
  • サービス構成

必要な属性が自動的に追加され、コードを記述しなくても、Microsoft VisualStudioによって単純な「HelloWorld」サービスが作成されます。

CodePlex

CodePlexは2006年6月にMicrosoftによってリリースされ、それ以来、.NETプロジェクトを正常に作成するために世界中の多くの開発者によって使用されてきました。WCFサービスアプリケーションを開発するためにCodePlexが提供するツールのいくつかは次のとおりです。

  • wscf.blue−これはMicrosoft Visual Studioアドインであり、WCFサービス操作の定義を容易にし、それに応じてコードスケルトンを生成する「契約優先」の開発ツールセットでもあります。同じための重要なリンクは-https://wscfblue.codeplex.com

  • WCFProxyGenerator−これもMicrosoft VisualStudioアドインです。このツールは、クライアント側の生成を拡張し、追加のエラー処理を提供するために使用されます。この特定の開発ツールに関する詳細については、次のWebサイトをご覧ください。https://wcfproxygenerator.codeplex.com

  • WCFMock− WCFサービスのテストは複雑な作業になる可能性があり、この開発ツールは、便利なクラスによるWCFサービスの単体テストに便利なソリューションを提供します。このツールの詳細については、次のWebサイトをご覧ください。https://wcfmock.codeplex.com

WCFサービスアプリケーションを簡単に開発するためのもう1つの無料ツールは、WCFStormです。そのLITEバージョンは、WCFサービスの動的な呼び出しとテスト、サービスバインディングの編集、WCFURLエンドポイントの変更などのための多くの優れた機能を提供します。

WCFには、さまざまな分散アプリケーションの開発を十分にサポートする階層化アーキテクチャがあります。アーキテクチャについては、以下で詳しく説明します。

契約

コントラクトレイヤーはアプリケーションレイヤーのすぐ隣にあり、サービスの操作とサービスが作成するアクセス可能な情報の種類を指定する実際のコントラクトと同様の情報が含まれています。契約は基本的に以下に簡単に説明する4つのタイプです-

  • Service contract −この契約は、エンドポイントの提供、および通信プロセスで使用されるプロトコルに関する情報をクライアントと外部に提供します。

  • Data contract−サービスによって交換されるデータは、データコントラクトによって定義されます。クライアントとサービスの両方がデータ契約に同意する必要があります。

  • Message contract−データコントラクトはメッセージコントラクトによって制御されます。これは主に、SOAPメッセージパラメータのタイプフォーマットのカスタマイズを行います。ここで、WCFは通信の目的でSOAP形式を採用していることに注意してください。SOAPはSimpleObject AccessProtocolの略です。

  • Policy and Binding−サービスとの通信には特定の前提条件があり、そのような条件はポリシーと拘束力のある契約によって定義されます。クライアントはこの契約に従う必要があります。

サービスランタイム

サービスランタイムレイヤーは、コントラクトレイヤーのすぐ下にあります。実行時に発生するさまざまなサービス動作を指定します。構成を受けてサービスランタイムに入る可能性のある動作には多くの種類があります。

  • Throttling Behavior −処理されるメッセージの数を管理します。

  • Error Behavior −内部サービスエラーの発生の結果を定義します。

  • Metadata Behavior −外部へのメタデータの可用性を指定します。

  • Instance Behavior −クライアントで使用できるようにするために作成する必要のあるインスタンスの数を定義します。

  • Transaction Behavior −障害が発生した場合に、トランザクション状態の変更を有効にします。

  • Dispatch Behavior −メッセージがWCFのインフラストラクチャによって処理される方法を制御します。

  • Concurrency Behavior −クライアント/サーバー通信中に並行して実行される機能を制御します。

  • Parameter Filtering −メソッドが呼び出される前にメソッドに対するパラメーターを検証するプロセスを特徴としています。

メッセージング

複数のチャネルで構成されるこのレイヤーは、主に2つのエンドポイント間で通信されるメッセージコンテンツを処理します。チャネルのセットはチャネルスタックを形成し、チャネルスタックを構成する2つの主要なタイプのチャネルは次のとおりです。

  • Transport Channels −これらのチャネルはスタックの最下部に存在し、HTTP、TCP、ピアツーピア、名前付きパイプ、MSMQなどのトランスポートプロトコルを使用してメッセージを送受信する責任があります。

  • Protocol Channels −スタックの最上位に存在するこれらのチャネルは、階層化チャネルとも呼ばれ、メッセージを変更することによってワイヤレベルのプロトコルを実装します。

アクティベーションとホスティング

WCFアーキテクチャの最後の層は、サービスが実際にホストされている場所、またはクライアントが簡単にアクセスできるように実行できる場所です。これは、以下で簡単に説明するさまざまなメカニズムによって実行されます。

  • IIS− IISは、インターネットインフォメーションサービスの略です。これは、サービスによってHTTPプロトコルを使用することで無数の利点を提供します。ここでは、サービスコードをアクティブ化するためのホストコードは必要ありません。代わりに、サービスコードが自動的にアクティブ化されます。

  • Windows Activation Service−これは一般にWASとして知られており、IIS7.0に付属しています。ここでは、TCPまたは名前付きパイププロトコルを使用して、HTTPベースと非HTTPベースの両方の通信が可能です。

  • Self-hosting−これは、WCFサービスがコンソールアプリケーションとして自己ホストされるメカニズムです。このメカニズムは、必要なプロトコルの選択と独自のアドレス指定スキームの設定に関して驚くべき柔軟性を提供します。

  • Windows Service −このメカニズムでWCFサービスをホストすると、ランタイムがアクティブ化されないため、サービスがアクティブ化されたままになり、クライアントがアクセスできるため、有利です。

WCFサービスの作成は、Microsoft Visual Studio 2012を使用した簡単なタスクです。以下に、概念をよりよく理解するために、必要なすべてのコーディングとともにWCFサービスを作成するための段階的な方法を示します。

  • Visual Studio2012を起動します。
  • 新しいプロジェクトをクリックし、[Visual C#]タブで[WCF]オプションを選択します。

加算、減算、乗算、除算などの基本的な算術演算を実行するWCFサービスが作成されます。メインコードは、1つのインターフェイスと1つのクラスの2つの異なるファイルにあります。

WCFには、1つ以上のインターフェイスとその実装済みクラスが含まれています。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServiceLibrary1 {
   // NOTE: You can use the "Rename" command on the "Refactor" menu to 
   // change the interface name "IService1" in both code and config file 
   // together.

   [ServiceContract]
   Public interface IService1 {
      [OperationContract]
      int sum(int num1, int num2);

      [OperationContract]
      int Subtract(int num1, int num2);

      [OperationContract]
      int Multiply(int num1, int num2);

      [OperationContract]
      int Divide(int num1, int num2);
   }

   // Use a data contract as illustrated in the sample below to add 
   // composite types to service operations.

   [DataContract]
   Public class CompositeType {
      Bool boolValue = true;
      String stringValue = "Hello ";

      [DataMember]
      Public bool BoolValue {
         get { return boolValue; }
         set { boolValue = value; }
      }

      [DataMember]   
      Public string StringValue {
         get { return stringValue; }
         set { stringValue = value; }
      }
   }
}

そのクラスの背後にあるコードを以下に示します。

using System;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Runtime.Serialization;
usingSystem.ServiceModel;
usingSystem.Text;

namespace WcfServiceLibrary1 {
   // NOTE: You can use the "Rename" command on the "Refactor" menu to 
   // change the class name "Service1" in both code and config file 
   // together.

   publicclassService1 :IService1 {
      // This Function Returns summation of two integer numbers
      
      publicint sum(int num1, int num2) {
         return num1 + num2;
      }
      
      // This function returns subtraction of two numbers. 
      // If num1 is smaller than number two then this function returns 0
      
      publicint Subtract(int num1, int num2) {
         if (num1 > num2) {
            return num1 - num2;
         }
         else {
            return 0;
         }
      }
      
      // This function returns multiplication of two integer numbers.
      publicint Multiply(int num1, int num2) {
         return num1 * num2;
      }
      
      // This function returns integer value of two integer number. 
      // If num2 is 0 then this function returns 1.
      publicint Divide(int num1, int num2) {
         if (num2 != 0) {
            return (num1 / num2);
         } else {
            return 1;
         }
      }
   }
}

このサービスを実行するには、VisualStudioの[スタート]ボタンをクリックします。

このサービスを実行している間、次の画面が表示されます。

合計方法をクリックすると、次のページが開きます。ここでは、任意の2つの整数を入力して、[呼び出す]ボタンをクリックできます。サービスは、これら2つの数値の合計を返します。

合計と同様に、メニューにリストされている他のすべての算術演算を実行できます。そして、ここに彼らのためのスナップがあります。

減算方法をクリックすると、次のページが表示されます。整数を入力し、[呼び出し]ボタンをクリックして、次のように出力を取得します-

Multiplyメソッドをクリックすると、次のページが表示されます。整数を入力し、[呼び出し]ボタンをクリックして、次のように出力を取得します-

Divideメソッドをクリックすると次のページが表示されます。整数を入力し、[呼び出し]ボタンをクリックして、次のように出力を取得します-

サービスが呼び出されると、ここから直接切り替えることができます。

WCFサービスを作成したら、次のステップは、クライアントアプリケーションがそれを利用できるように、それをホストすることです。これは、WCFサービスホスティングとして知られています。WCFサービスは、以下の4つの方法のいずれかを使用してホストできます。

  • IIS Hosting− IISは、インターネットインフォメーションサービスの略です。その動作モデルは、WCFサービスをホストしている間のASP.NETの動作モデルと似ています。IISホスティングの最も優れた機能は、サービスのアクティブ化が自動的に処理されることです。IISホスティングは、プロセスヘルスの監視、アイドルシャットダウン、プロセスリサイクル、およびWCFサービスホスティングを容易にするその他の多くの機能も提供します。

  • Self-Hosting− WCFサービスが管理対象アプリケーションでホストされている場合、それはセルフホスティングと呼ばれます。開発者は、ServiceHostの初期化に必要なコーディングを作成する必要があります。セルフホスティングでは、WCFサービスは、コンソールアプリケーション、Windowsフォームなどのさまざまなアプリケーションでホストできます。

  • WAS Hosting − Windows Activation Service(WAS)でWCFサービスをホストすることは、プロセスのリサイクル、アイドル時間の管理、共通の構成システム、HTTP、TCPなどのサポートなどの機能のために最も有利です。

  • Windows Service Hosting−ローカルシステムクライアントの場合、WCFサービスをウィンドウサービスとしてホストするのが最適であり、これはウィンドウサービスホスティングと呼ばれます。Windowsのすべてのバージョンがこのタイプのホスティングをサポートしており、ここでは、サービスコントロールマネージャーがWCFサービスのプロセスライフサイクルを制御できます。

IIS(インターネットインフォメーションサービス)でWCFサービスをホストすることは、段階的なプロセスです。IISホスティングは、プロセスを理解するためのスクリーンショットだけでなく、必要なコーディングとともに詳細に以下に示されています。

Step 1− Visual Studio 2012を起動し、[ファイル]→[新規]→[Webサイト]をクリックします。「WCFサービス」と場所をhttpとして選択します。これにより、IISでサービスがホストされます。[OK]をクリックします。

Step 2 −インターフェースの背後にあるコードを以下に示します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

// NOTE: You can use the "Rename" command on the "Refactor" menu to 
// change the interface name "IService" in both code and config file 
// together.

[ServiceContract]
Public interface IService {
   [OperationContract]
   String GetData(int value);

   [OperationContract]
   CompositeType GetDataUsingDataContract(CompositeType composite);

   // TODO: Add your service operations here
}

// Use a data contract as illustrated in the sample below to add 
// composite types to service operations.

[DataContract]
Public class CompositeType {
   Bool boolValue = true;
   String stringValue = "Hello ";

   [DataMember]
   Public bool BoolValue {
      get { return boolValue; }
      set { boolValue = value; }
   }

   [DataMember]
   Public string StringValue {
      get { return stringValue; }
      set { stringValue = value; }
   }
}

Step 3 −クラスファイルの背後にあるコードを以下に示します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

// NOTE: You can use the "Rename" command on the "Refactor" menu to 
// change the class name "Service" in code, svc and config file 
// together.

Public class Service : IService {
   Public string GetData(int value) {
      Return string.Format("You entered: {0}", value);
   }

   Public CompositeType GetDataUsingDataContract(CompositeType composite) {
      if(composite == null) {
         thrownewArgumentNullException("composite");
      }
      
      if(composite.BoolValue) {
         composite.StringValue += "Suffix";
      }
      return composite;
   }
}

Step 4−サービスファイル(.svc)には、サービスの名前とファイル名の背後にあるコードが含まれています。このファイルは、サービスについて知るために使用されます。

<%@ ServiceHost Language = "C#" Debug = "true" Service = "Service" 
   CodeBehind = "~/App_Code/Service.cs" %>

Step 5−サーバー側の構成は構成ファイルに記載されています。ここでは、「wsHttpBinding」に構成されているエンドポイントが1つだけ言及されています。バインディングが異なる複数のエンドポイントを持つこともできます。IISでホストするため、httpバインディングのみを使用する必要があります。

<?xml version = "1.0"?>
<configuration>
   <!-- 
      Note: As an alternative to hand editing this file you can use the 
         web admin tool to configure settings for your application. Use
         the Website->Asp.Net Configuration option in Visual Studio.
         A full list of settings and comments can be found in 
         machine.config.comments usually located in 
         \Windows\Microsoft.Net\Framework\vx.x\Config 
   -->
   <configSections>
      <sectionGroup name = "system.web.extensions"  
         ype = "System.Web.Configuration.SystemWebExtensionsSectionGroup, 
         System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
         PublicKeyToken = 31BF3856AD364E35">
      
         <sectionGroup name = "scripting" 
            type = "System.Web.Configuration.ScriptingSectionGroup, 
            System.Web.Extensions, Version = 3.5.0.0, Culture = neutral,     
            PublicKeyToken = 31BF3856AD364E35">
      
            <section name = "scriptResourceHandler" 
               type = "System.Web.Configuration.ScriptingScriptResourceHandlerSection, 
               System.Web.Extensions, Version = 3.5.0.0, 
               Culture = neutral, PublicKeyToken = 31BF3856AD364E35" 
               requirePermission = "false" 
               allowDefinition = "MachineToApplication"/>
      
            <sectionGroup name = "webServices" 
               type = "System.Web.Configuration.ScriptingWebServicesSectionGroup, 
               System.Web.Extensions, Version = 3.5.0.0, 
               Culture = neutral, PublicKeyToken = 31BF3856AD364E35">
   
               <section name = "jsonSerialization" 
                  type = "System.Web.Configuration.ScriptingJsonSerializationSection, 
                  System.Web.Extensions, Version = 3.5.0.0, 
                  Culture = neutral, PublicKeyToken = 31BF3856AD364E35" 
                  requirePermission = "false" allowDefinition = "Everywhere"/>

               <section name = "profileService" 
                  type = "System.Web.Configuration.ScriptingProfileServiceSection, 
                  System.Web.Extensions, Version = 3.5.0.0, 
                  Culture = neutral, PublicKeyToken = 31BF3856AD364E35" 
                  requirePermission = "false" 
                  allowDefinition = "MachineToApplication"/>

               <section name = "authenticationService" 
                  type = "System.Web.Configuration.ScriptingAuthenticationServiceSection, 
                  System.Web.Extensions, Version = 3.5.0.0, 
                  Culture = neutral, PublicKeyToken = 31BF3856AD364E35" 
                  requirePermission = "false" 
                  allowDefinition = "MachineToApplication"/>

               <section name = "roleService" 
                  type = "System.Web.Configuration.ScriptingRoleServiceSection, 
                  System.Web.Extensions, Version = 3.5.0.0, 
                  Culture = neutral, PublicKeyToken = 31BF3856AD364E35" 
                  requirePermission = "false" 
                  allowDefinition = "MachineToApplication"/>
      
            </sectionGroup>
         </sectionGroup>
      </sectionGroup>
   </configSections>
   
<appSettings/>
   <connectionStrings/>
   <system.web>
      <!-- 
         Set compilation debug="true" to insert debugging 
         symbols into the compiled page. Because this 
         affects performance, set this value to true only 
         during development.
      -->
      
      <compilation debug = "true">
         <assemblies> 
         
            <add assembly = "System.Core, Version = 3.5.0.0, Culture = neutral, 
               PublicKeyToken = B77A5C561934E089"/>
            
            <add assembly = "System.Web.Extensions, Version = 3.5.0.0, 
               Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/>
            
            <add assembly = "System.Data.DataSetExtensions, Version = 3.5.0.0, 
               Culture = neutral, PublicKeyToken = B77A5C561934E089"/>
            
            <add assembly = "System.Web.Extensions, Version = 3.5.0.0, 
               Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/>
            
            <add assembly = "System.Xml.Linq, Version = 3.5.0.0, Culture = neutral, 
               PublicKeyToken = B77A5C561934E089"/>
            
         </assemblies>
      </compilation>
      
         <!--
            The <authentication> section enables configuration 
            of the security authentication mode used by 
            ASP.NET to identify an incoming user. 
         -->
         
      <authentication mode="Windows"/>
         <!--
            The <customErrors> section enables configuration 
            of what to do if/when an unhandled error occurs 
            during the execution of a request. Specifically, 
            it enables developers to configure html error pages 
            to be displayed in place of a error stack trace.

            <customErrors mode = "RemoteOnly" defaultRedirect = "GenericErrorPage.htm">
               <error statusCode = "403" redirect = "NoAccess.htm" />
               <error statusCode = "404" redirect = "FileNotFound.htm" />
            </customErrors>
         -->
         
         <pages>
            <controls>
               <add tagPrefix = "asp" namespace = "System.Web.UI" 
                  assembly = "System.Web.Extensions, Version = 3.5.0.0, 
                  Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/>
               
               <add tagPrefix = "asp" namespace = "System.Web.UI.WebControls" 
                  assembly = "System.Web.Extensions, Version = 3.5.0.0, 
                  Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/>
               
            </controls>
         </pages>
         
         <httpHandlers>
            <remove verb = "*" path = "*.asmx"/>
            
            <add verb = "*" path = "*.asmx" validate = "false" 
               type = "System.Web.Script.Services.ScriptHandlerFactory, 
               System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
               PublicKeyToken = 31BF3856AD364E35"/>
            
            <add verb = "*" path = "*_AppService.axd" validate = "false" 
               type = "System.Web.Script.Services.ScriptHandlerFactory, 
               System.Web.Extensions, Version = 3.5.0.0, Culture = neutral,
               PublicKeyToken = 31BF3856AD364E35"/>
            
            <add verb = "GET,HEAD" path = "ScriptResource.axd" 
               type = "System.Web.Handlers.ScriptResourceHandler, 
               System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
               PublicKeyToken = 31BF3856AD364E35" validate = "false"/>
         </httpHandlers>
         
         <httpModules>
            <add name = "ScriptModule" 
               type = "System.Web.Handlers.ScriptModule, 
               System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
               PublicKeyToken = 31BF3856AD364E35"/>
         </httpModules>
   </system.web>
   
   <system.codedom>
      <compilers>
      
         <compiler language = "c#;cs;csharp" extension = ".cs" 
            warningLevel = "4" type = "Microsoft.CSharp.CSharpCodeProvider, 
            System, Version = 2.0.0.0, Culture = neutral, 
            PublicKeyToken = b77a5c561934e089">
         
            <providerOption name = "CompilerVersion" value = "v3.5"/>
            <providerOption name = "WarnAsError" value = "false"/>

         </compiler>

         <compiler language = "vb;vbs;visualbasic;vbscript" extension = ".vb" 
            warningLevel = "4" type = "Microsoft.VisualBasic.VBCodeProvider, 
            System, Version = 2.0.0.0, Culture = neutral, 
            PublicKeyToken = b77a5c561934e089">

            <providerOption name = "CompilerVersion" value = "v3.5"/>
            <providerOption name = "OptionInfer" value = "true"/>
            <providerOption name = "WarnAsError" value = "false"/>
            
         </compiler>
      </compilers>
      
   </system.codedom>
   <!-- 
      The system.webServer section is required for running ASP.NET AJAX 
      under Internet Information Services 7.0.  
      It is not necessary for previous version of IIS.
   -->
   <system.webServer>
      <validation validateIntegratedModeConfiguration="false"/>
      
      <modules>
         <remove name = "ScriptModule"/>
         <add name = "ScriptModule" preCondition = "managedHandler" 
            type = "System.Web.Handlers.ScriptModule, 
            System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
            PublicKeyToken = 31BF3856AD364E35"/>
      </modules>
      
      <handlers>
         <remove name = "WebServiceHandlerFactory-Integrated"/>
         <remove name = "ScriptHandlerFactory"/>
         <remove name = "ScriptHandlerFactoryAppServices"/>
         <remove name = "ScriptResource"/>
         
         <add name = "ScriptHandlerFactory" verb = "*" path = "*.asmx" 
            preCondition = "integratedMode" 
            type = "System.Web.Script.Services.ScriptHandlerFactory, 
            System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
            PublicKeyToken = 31BF3856AD364E35"/>    
         
         <add name = "ScriptHandlerFactoryAppServices" 
            verb = "*" path = "*_AppService.axd" preCondition = "integratedMode" 
            type = "System.Web.Script.Services.ScriptHandlerFactory, 
            System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
            PublicKeyToken = 31BF3856AD364E35"/>
         
         <add name = "ScriptResource" preCondition = "integratedMode" 
            verb = "GET,HEAD" path = "ScriptResource.axd" 
            type = "System.Web.Handlers.ScriptResourceHandler, 
            System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
            PublicKeyToken = 31BF3856AD364E35"/>
      </handlers>
      
      <!--To browse web app root directory during debugging, 
         set the value below to true. Set to false before deployment to 
         avoid disclosing web app folder information.-->
      
      <directoryBrowse enabled = "true"/>
   </system.webServer>
   
   <runtime>
      <assemblyBinding appliesTo = "v2.0.05727" xmlns =" urn:schemas-microsoft-com:asm.v1">
      
         <dependentAssembly>
            <assemblyIdentity name = "System.Web.Extensions" publicKeyToken = "31bf3856ad364e35"/>
            <bindingRedirect oldVersion = "1.0.0.0-1.1.0.0" newVersion = "3.5.0.0"/>
         </dependentAssembly>
         
         <dependentAssembly>
            <assemblyIdentity name = "System.Web.Extensions.Design" publicKeyToken =" 31bf3856ad364e35"/>
            <bindingRedirect oldVersion = "1.0.0.0-1.1.0.0" newVersion = "3.5.0.0"/>
         </dependentAssembly>
         
      </assemblyBinding>
   </runtime>
   
   <system.serviceModel>
      <services>
         <service name = "Service" behaviorConfiguration = "ServiceBehavior">
         <!-- Service Endpoints -->
            <endpoint address = "" binding = "basicHttpBinding" contract = "IService">
               <!-- 
                  Upon deployment, the following identity element should be removed or replaced 
                  to reflect the identity under which the deployed service runs. If removed, 
                  WCF will infer an appropriate identity automatically.
               -->

               <identity>
                  <dns value="localhost"/>
               </identity>

            </endpoint>
            <endpoint address = "mex" binding = "mexHttpBinding" contract = "IMetadataExchange"/>
            
         </service>
      </services>
      
      <behaviors> 
         <serviceBehaviors>
            <behavior name = "ServiceBehavior">
               <!-- To avoid disclosing metadata information, set the value below 
                  to false before deployment -->
               
               <serviceMetadata httpGetEnabled = "true"/>
               
               <!-- To receive exception details in faults for debugging purposes, 
                  set the value below to true. 
                  Set to false before deployment to false avoid 
                  disclosing exception information -->
               
               <serviceDebug includeExceptionDetailInFaults = "false"/>
            </behavior>
         </serviceBehaviors>
      </behaviors>
      
   </system.serviceModel>
</configuration>

Step 6−構成ファイルに記載されているアドレスとともに、サービスファイル名を記載する必要があります。IISのスクリーンショットをここに示します。

[スタート]→[実行]→[inetmgr]をクリックすると、次のウィンドウが開きます。

Step 7 −次の画面が表示されるアプリケーションを実行します。

ここでは、WCFサービスはコンソールアプリケーションでホストされています。以下に示すのは、プロセス全体を説明する、適切なステップを順番に実行するプロセスです。

Step 1−まず、サービス契約とその実装を作成しましょう。コンソールアプリケーションを作成し、MyCalculatorServiceという名前を付けます。これは、2つの数値の加算を返す簡単なサービスです。

Step 2−ここで、ソリューションエクスプローラーで参照を右クリックし、[参照の追加]をクリックします。次のウィンドウが開きます。System.ServiceModel参照をプロジェクトに追加します。

Step 3− ISimpleCalculatorインターフェースを作成し、以下に示すように、ServiceContract属性とOperationContract属性をクラスと関数に追加します。これらの契約については、後のセッションで詳しく説明します。これらの契約により、このサービスを使用するためのメソッドが外部に公開されます。

Step 4 −このファイルの背後にあるコードは次のとおりです−

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace MyCalculatorWCFService {
   [ServiceContract()]
   Public interface ISimpleCalculator {
      [OperationContract()]
      int Add(int num1, int num2);
   }
}

Step 5 − MyCalculatorServiceは、以下に示すIMyCalculatorServiceインターフェイスの実装クラスです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyCalculatorWCFService {
   Class SimpleCalculator : ISimpleCalculator {
      Public int Add(int num1, int num2) {
         return num1 + num2;
      }
   }
}

Step 6−これで、サービスの準備が整いました。ホスティングプロセスの実装に取り​​掛かりましょう。新しいコンソールアプリケーションを作成し、「MyCalculatorWCFServiceHost」という名前を付けます。

Step 7 −system.servicemodelとプロジェクトMyCalculatorWCFServiceの参照を追加します。

この背後にあるコードは次のとおりです-

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyCalculatorWCFService;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace MyCalculatorWCFServiceHost {
   class Program {
      static void Main(string[] args) {
         //Create a URI to serve as the base address
         UrihttpUrl = newUri("http://localhost:8090/MyCalculatorWCFService/SimpleCalculator");
         
         //Create ServiceHost
         ServiceHost host = newServiceHost(typeof(MyCalculatorWCFService.ISimpleCalculator), httpUrl);
         
         //Add a service endpoint
         host.AddServiceEndpoint(typeof(MyCalculatorWCFService.ISimpleCal culator), newWSHttpBinding(), "");
         
         //Enable metadata exchange
         ServiceMetadataBehaviorsmb = newServiceMetadataBehavior();
         smb.HttpGetEnabled = true;
         host.Description.Behaviors.Add(smb);

         //Start the Service
         host.Open();
         Console.WriteLine("Service is host at " + DateTime.Now.ToString());
         Console.WriteLine("Host is running... Press  key to stop");
         Console.ReadLine();
      }
   }
}

WASホスティングの概念を理解するには、システムがどのように構成され、サービスコントラクトがどのように作成され、ホストされたサービスへのさまざまなバインディングを可能にするかを理解する必要があります。

まず、非プロトコルに対してWCFを有効にします。サービスの作成を開始する前に、WASをサポートするようにシステムを構成する必要があります。以下は、WASを構成する手順です。

  • [スタート]メニュー→[コントロールパネル]→[プログラムと機能]を​​クリックし、左側のウィンドウで[Windowsコンポーネントをオンまたはオフにする]をクリックします。

  • [Microsoft .Net Framework 3.0]を展開し、[Windows Communication FoundationHTTPアクティベーション]と[WindowsCommunicationFoundation非HTTPアクティベーション]を有効にします。

  • 次に、デフォルトのWebサイトにBindingを追加する必要があります。例として、デフォルトのWebサイトをTCPプロトコルにバインドします。[スタート]メニュー→[プログラム]→[アクセサリ]に移動します。「コマンドプロンプト」を右クリックし、コンテキストメニューから「管理者として実行」を選択します。

  • 次のコマンドを実行します-

C:\Windows\system32\inetsrv> appcmd.exe set site "Default Web Site" -+bindings.[protocol='net.tcp',bindingInformation='808:*']

このコマンドは、「C:\ Windows \ system32 \ inetsrv \ config」ディレクトリにあるapplicationHost.configファイルを変更することにより、net.tcpサイトバインディングをデフォルトのWebサイトに追加します。同様に、デフォルトのWebサイトにさまざまなプロトコルを追加できます。

WASホステッドサービスの作成

Step-1 −以下に示すように、Visual Studio 2008を開き、[新規]→[Webサイト]をクリックして、テンプレートから[WCFサービス]を選択し、[場所]をHTTPとして選択します。

Step-2−インターフェースIMathServiceを作成して、コントラクトを作成します。ServiceContract属性をインターフェースに追加し、OperationContract属性をメソッド宣言に追加します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

// NOTE: You can use the "Rename" command on the "Refactor" menu to 
// change the interface name "IService" in both code and config file 
// together.

[ServiceContract]

Public interface IMathService {
   [OperationContract]
   int Add(int num1, int num2);

   [OperationContract]
   int Subtract(int num1, int num2);
}

Step-3 −IMathServiceインターフェースの実装を以下に示します−

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

// NOTE: You can use the "Rename" command on the "Refactor" menu to 
// change the class name "Service" in code, svc and config file 
// together.

Public class MathService : IMathService {
   Public int Add(int num1, int num2) {
      return num1 + num2;
   }
   Public int Subtract(int num1, int num2) {
      return num1 - num2;
   }
}

Step-4 −サービスファイルを以下に示します。

<%@ServiceHostLanguage="C#"Debug="true"Service="MathService"CodeBehind="~/App_Code/MathService.cs"%>

Step-5− web.Configファイルで、「netTcpBinding」バインディングを使用してエンドポイントを作成すると、サービスメタデータがメタデータエクスチェンジポイントを使用して公開されます。したがって、アドレスを「mex」、バインディングを「mexTcpBinding」としてメタデータ交換エンドポイントを作成します。サービスメタデータを公開しないと、net.tcpアドレスを使用してプロキシを作成することはできません。

svcutil.exe net.tcp://localhost/WASHostedService/MathService.svc).
<?xml version = "1.0" ?>
<configuration>
   <!--
      Note: As an alternative to hand editing this file you can use the 
         web admin tool to configure settings for your application. Use
         the Website->Asp.Net Configuration option in Visual Studio.
         A full list of settings and comments can be found in 
         machine.config.comments usually located in 
         \Windows\Microsoft.Net\Framework\vx.x\Config 
   -->
   <configSections>
      <sectionGroup name = "system.web.extensions" 
         type = "System.Web.Configuration.SystemWebExtensionsSectionGroup, 
         System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
         PublicKeyToken = 31BF3856AD364E35">
		
         <sectionGroup name = "scripting" 
            type = "System.Web.Configuration.ScriptingSectionGroup, 
            System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
            PublicKeyToken =3 1BF3856AD364E35">

            <section name = "scriptResourceHandler" 
               type = "System.Web.Configuration.ScriptingScriptResourceHandlerSection, 
               System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
               PublicKeyToken = 31BF3856AD364E35" 
               requirePermission = "false" 
               allowDefinition = "MachineToApplication"/>

            <sectionGroup name = "webServices" 
               type = "System.Web.Configuration.ScriptingWebServicesSectionGroup, 
               System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
               PublicKeyToken = 31BF3856AD364E35">

               <section name = "jsonSerialization" 
                  type = "System.Web.Configuration.ScriptingJsonSerializationSection, 
                  System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
                  PublicKeyToken = 31BF3856AD364E35" requirePermission = "false" 
                  allowDefinition = "Everywhere"/>

               <section name = "profileService" 		     
                  type = "System.Web.Configuration.ScriptingProfileServiceSection, 
                  System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
                  PublicKeyToken = 31BF3856AD364E35" requirePermission = "false" 
                  allowDefinition = "MachineToApplication"/>

               <section name = "authenticationService" 			     
                  type = "System.Web.Configuration.ScriptingAuthenticationServiceSection, 
                  System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
                  PublicKeyToken = 31BF3856AD364E35" requirePermission = "false" 
                  allowDefinition = "MachineToApplication"/>

               <section name = "roleService"	
                  type = "System.Web.Configuration.ScriptingRoleServiceSection, 
                  System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
                  PublicKeyToken = 31BF3856AD364E35" requirePermission = "false"
                  allowDefinition = "MachineToApplication"/>

            </sectionGroup>
         </sectionGroup>
      </sectionGroup>
   </configSections>
   
   <appSettings/>
   <connectionStrings/>
   
   <system.web>
      <!--
         Set compilation debug="true" to insert debugging 
         symbols into the compiled page. Because this 
         affects performance, set this value to true only 
         during development.
      -->
      <compilation debug = "true">
         <assemblies>
            <add assembly = "System.Core, Version = 3.5.0.0, 
               Culture = neutral, PublicKeyToken = B77A5C561934E089"/>
            
            <add assembly = "System.Web.Extensions, Version = 3.5.0.0, 
               Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/>
            
            <add assembly = "System.Data.DataSetExtensions, 
               Version = 3.5.0.0, Culture = neutral,                  
               PublicKeyToken = B77A5C561934E089"/>
            
            <add assembly = "System.Web.Extensions, Version = 3.5.0.0, 
               Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/>
            
            <add assembly = "System.Xml.Linq, 
               Version = 3.5.0.0, Culture = neutral, 
               PublicKeyToken = B77A5C561934E089"/>
         </assemblies>
      </compilation>
      
      <!--
         The <authentication> section enables configuration          
         of the security authentication mode used by 
         ASP.NET to identify an incoming user. 
      -->
      
      <authentication mode="Windows"/>
      
      <!--
         The <customErrors> section enables configuration 
         of what to do if/when an unhandled error occurs 
         during the execution of a request. Specifically, 
         it enables developers to configure html error pages 
         to be displayed in place of a error stack trace.
         <customErrors mode = "RemoteOnly" defaultRedirect = "GenericErrorPage.htm">
         <error statusCode = "403" redirect = "NoAccess.htm" />
         <error statusCode = "404" redirect = "FileNotFound.htm" />
         </customErrors>
      -->
      
      <pages>
         <controls>
            <add tagPrefix = "asp" namespace = "System.Web.UI" 
               assembly = "System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
               PublicKeyToken = 31BF3856AD364E35"/>
            
            <add tagPrefix = "asp" namespace = "System.Web.UI.WebControls"
               assembly = "System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
               PublicKeyToken = 31BF3856AD364E35"/>
         </controls>
      </pages>
      
      <httpHandlers>
         <remove verb = "*" path = "*.asmx"/>
         
         <add verb =" *" path =" *.asmx" validate="false"         
            type = "System.Web.Script.Services.ScriptHandlerFactory, 
            System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
            PublicKeyToken = 31BF3856AD364E35"/>
         
         <add verb = "*" path = "*_AppService.axd" validate = "false" 
            type = "System.Web.Script.Services.ScriptHandlerFactory,System.Web.Extensions, 
            Version = 3.5.0.0, Culture = neutral, 
            PublicKeyToken = 31BF3856AD364E35"/>
         
         <add verb = "GET,HEAD" path = "ScriptResource.axd"        
            type = "System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, 
            Version = 3.5.0.0, Culture = neutral, 
            PublicKeyToken = 31BF3856AD364E35" validate = "false"/>
      </httpHandlers>
      
      <httpModules>
         <add name = "ScriptModule" 
            type = "System.Web.Handlers.ScriptModule, 
            System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
            PublicKeyToken = 31BF3856AD364E35"/>
      </httpModules>
      
   </system.web>
   
   <system.codedom>
      <compilers>
         
         <compiler language = "c#;cs;csharp" extension = ".cs" warningLevel = "4" 
            type = "Microsoft.CSharp.CSharpCodeProvider, System, 
            Version = 2.0.0.0, Culture = neutral,                 
            PublicKeyToken = b77a5c561934e089">
         
            <providerOption name = "CompilerVersion" value = "v3.5"/>
            <providerOption name = "WarnAsError" value = "false"/>
         </compiler>
         
         <compiler language = "vb;vbs;visualbasic;vbscript" 
            extension = ".vb" warningLevel = "4" 
            type = "Microsoft.VisualBasic.VBCodeProvider, System, 
            Version = 2.0.0.0, Culture = neutral,                  
            PublicKeyToken = b77a5c561934e089">
         
            <providerOption name = "CompilerVersion" value = "v3.5"/>
            <providerOption name = "OptionInfer" value = "true"/>
            <providerOption name = "WarnAsError" value = "false"/>
         </compiler>
      
      </compilers>
   </system.codedom>
   
   <!--
      The system.webServer section is required for running ASP.NET AJAX under 
      Internet Information Services 7.0. It is not necessary for previous version of IIS.
   -->
   
   <system.webServer>
      <validation validateIntegratedModeConfiguration = "false"/>
      
      <modules>
         <remove name = "ScriptModule"/>
         <add name = "ScriptModule" preCondition = "managedHandler"         
            type = "System.Web.Handlers.ScriptModule, System.Web.Extensions, 
            Version = 3.5.0.0, Culture = neutral, 
            PublicKeyToken = 31BF3856AD364E35"/>
      </modules>
      
      <handlers>
         <remove name = "WebServiceHandlerFactory-Integrated"/>
         <remove name = "ScriptHandlerFactory"/>
         <remove name = "ScriptHandlerFactoryAppServices"/>
         <remove name = "ScriptResource"/>
         
         <add name = "ScriptHandlerFactory" 
            verb = "*" path = "*.asmx" preCondition = "integratedMode"              
            type = "System.Web.Script.Services.ScriptHandlerFactory, 
            System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
            PublicKeyToken = 31BF3856AD364E35"/>
         
         <add name = "ScriptHandlerFactoryAppServices" 
            verb = "*" path = "*_AppService.axd" preCondition = "integratedMode" 
            type = "System.Web.Script.Services.ScriptHandlerFactory, 
            System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
            PublicKeyToken = 31BF3856AD364E35"/>
         
         <add name = "ScriptResource" preCondition = "integratedMode" 
            verb = "GET,HEAD" path = "ScriptResource.axd" 
            type = "System.Web.Handlers.ScriptResourceHandler, 
            System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, 
            PublicKeyToken = 31BF3856AD364E35"/>
         
      </handlers>
      <!--
         To browse web app root directory during debugging, set the value below to true. 
         Set to false before deployment to avoid disclosing web app folder information.
      -->
      <directoryBrowse enabled="true"/>
   </system.webServer>
   
   <runtime>
      <assemblyBinding appliesTo = "v2.0.05727" xmlns = "urn:schemas-microsoft-com:asm.v1">
      
         <dependentAssembly>
            <assemblyIdentity name = "System.Web.Extensions" publicKeyToken = "31bf3856ad364e35"/>
            <bindingRedirect oldVersion = "1.0.0.0-1.1.0.0" newVersion = "3.5.0.0"/>
         </dependentAssembly>
         
         <dependentAssembly>
            <assemblyIdentity name = "System.Web.Extensions.Design" publicKeyToken = "31bf3856ad364e35"/>
            <bindingRedirect oldVersion = "1.0.0.0-1.1.0.0" newVersion = "3.5.0.0"/>
         </dependentAssembly>
         
      </assemblyBinding>
   </runtime>
   
   <system.serviceModel>
      <services>
         <service behaviorConfiguration = "ServiceBehavior" name = "Service">
            <endpoint address = "" binding = "basicHttpBinding" contract = "IMathService">
            
            <identity>
               <dns value = "localhost" />
            </identity>
            
            </endpoint>
            <endpoint address = "mex" binding = "mexHttpBinding" contract = "IMetadataExchange"/>
         </service>
      </services>
      
      <behaviors>
         <serviceBehaviors>
            <behavior name = "ServiceBehavior">
               <!-- 
                  To avoid disclosing metadata information, set the value below 
                  to false before deployment. 
               -->
               <serviceMetadata httpGetEnabled="true"/>
               
               <!-- 
                  To receive exception details in faults for debugging purposes, 
                  set the value below to true. Set to false before deployment to avoid 
                  disclosing exception information 
               -->
               <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
         </serviceBehaviors>
      </behaviors>
      
   </system.serviceModel>
</configuration>

ホストされたサービスへのさまざまなバインディングを有効にする

  • [スタート]メニュー→[プログラム]→[アクセサリ]に移動します。「コマンドプロンプト」を右クリックし、コンテキストメニューから「管理者として実行」を選択します。

  • 次のコマンドを実行します-

C:\Windows\system32\inetsrv>appcmd set app "Default Web Site/WASHostedService" /enabledProtocols:http,net.tcp

次の出力が生成されます-

Windowsサービスホスティングの操作は簡単です。以下に、プロセスを簡単に説明するために必要なコーディングとスクリーンショットを含む手順を示します。

Step 1−次に、WCFサービスを作成しましょう。Visual Studio 2008を開き、[新規]→[プロジェクト]をクリックして、テンプレートから[クラスライブラリ]を選択します。

Step 2−参照System.ServiceModelをプロジェクトに追加します。これは、WCFサービスの作成に使用されるコアアセンブリです。

Step 3−次に、ISimpleCalulatorインターフェイスを作成できます。以下に示すように、サービスおよび運用契約属性を追加します-

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace WindowsServiceHostedService{
   [ServiceContract]
   public interfaceISimpleCalculator {
      [OperationContract]
      int Add(int num1, int num2);

      [OperationContract]
      int Subtract(int num1, int num2);

      [OperationContract]
      int Multiply(int num1, int num2);

      [OperationContract]
      double Divide(int num1, int num2);
   }
}

Step 4 −以下に示すようにISimpleCalculatorインターフェースを実装します−

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsServiceHostedService {
   Class SimpleCalulator : ISimpleCalculator {
      Public int Add(int num1, int num2) {
         return num1 + num2;
      }
      Public int Subtract(int num1, int num2) {
         return num1 - num2;
      }
      Public int Multiply(int num1, int num2) {
         return num1 * num2;
      }
      Public double Divide(int num1, int num2) {
         if (num2 != 0)
            return num1 / num2;
         else
            return 0;
      }
   }
}

Step 5−プロジェクトをビルドし、dllを取得します。これで、WCFサービスの準備が整いました。WindowsサービスでWCFサービスをホストする方法を見ていきます。

Note−このプロジェクトでは、同じプロジェクトで契約とサービス(実装)の両方を作成していると述べられています。ただし、両方が異なるプロジェクトにある場合は、常に良い習慣です。

Step 6 − Visual Studio 2008を開き、[新規]→[プロジェクト]をクリックして、[Windowsサービス]を選択します。

Step 7−プロジェクトへの参照として「WindowsServiceHostedService.dll」を追加します。このアセンブリはサービスとして機能します。

Step 8−サービスのOnStartメソッドを使用して、WCFのホスティングコードを記述できます。1つのサービスホストオブジェクトのみを使用していることを確認する必要があります。OnStopメソッドは、サービスホストを閉じるために使用されます。次のコードは、WindowsサービスでWCFサービスをホストする方法を示しています。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace WCFHostedWindowsService {
   Partial class WCFHostedWindowsService : ServiceBase {
      ServiceHostm_Host;

      Public WCFHostedWindowsService() {
         InitializeComponent();
      }
      Private void InitializeComponent() {
         thrownewNotImplementedException();
      }
      protectedoverridevoidOnStart(string[] args) {
         if (m_Host != null) {
            m_Host.Close();
         }
        
         //Create a URI to serve as the base address
         UrihttpUrl = newUri("http://localhost:8090/WindowsServiceHostedService/SimpleCalculator");
        
         //Create ServiceHost
         m_Host = newServiceHost typeof(WindowsServiceHostedService.SimpleCalulator), httpUrl);
        
         //Add a service endpoint
         m_Host.AddServiceEndpoint (typeof(WindowsServiceHostedService.ISimpleCalculator), newWSHttpBinding(), "");
        
         //Enable metadata exchange
         ServiceMetadataBehaviorsmb = newServiceMetadataBehavior();
         smb.HttpGetEnabled = true;
         m_Host.Description.Behaviors.Add(smb);
        
         //Start the Service
         m_Host.Open();
      }
      protectedoverridevoidOnStop() {
         if (m_Host != null) {
            m_Host.Close();
            m_Host = null;
         }
      }
      staticvoid Main() {
         ServiceBase[] ServicesToRun;
         ServicesToRun = newServiceBase[] { 
            newWCFHostedWindowsService();
         }   
         ServiceBase.Run(ServicesToRun);
      }
   }
}

Step 9−サービスをインストールするには、WindowsサービスのInstallerクラスが必要です。したがって、Installerクラスから継承された新しいInstallerクラスをプロジェクトに追加します。以下に示すのは、サービスのサービス名、スタートアップの種類などを示すコードです。

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceProcess;
using System.Configuration.Install;
using System.ComponentModel;
using System.Configuration;

namespace WCFHostedWindowsService {
   [RunInstaller(true)]
   Public class WinServiceInstaller : Installer {
      Private ServiceProcessInstaller process;
      Private ServiceInstaller service;

      Public WinServiceInstaller() {
         process = newServiceProcessInstaller();
         process.Account = ServiceAccount.NetworkService;
         service = newServiceInstaller();
         
         service.ServiceName = "WCFHostedWindowsService";
         service.DisplayName = "WCFHostedWindowsService";
         service.Description = "WCF Service Hosted";
         service.StartType = ServiceStartMode.Automatic;
         
         Installers.Add(process);
         Installers.Add(service);
      }
   }
}

Step 10−プロジェクトをビルドして、実行可能ファイルWCFHostedWindowsService.exeを取得します。次に、VisualStudioコマンドプロンプトを使用してサービスをインストールする必要があります。したがって、[スタート]→[すべてのプログラム]→[Microsoft Visual Studio2008]→[VisualStudioツール]→[VisualStudioコマンドプロンプト]をクリックして、コマンドプロンプトを開きます。install utilユーティリティアプリケーションを使用すると、次のようにサービスをインストールできます。

WCFサービスを使用すると、他のアプリケーションがそれらにアクセスしたり、それらを利用したりできます。WCFサービスは、ホスティングの種類に応じてさまざまな方法で利用できます。ここでは、次の一般的なホスティングオプションのそれぞれについてWCFサービスを利用するための段階的な方法を説明しています-

  • IIS5 / 6でホストされているWCFサービスを使用する
  • 自己ホスト型のWCFサービスを使用する
  • Windows ActivationServiceでホストされているWCFサービスを使用する
  • WindowsサービスでホストされているWCFサービスの使用

IIS5 / 6でホストされているWCFサービスの使用

IIS 5/6でホストされているWCFサービスの利用プロセスについては、以下で詳しく説明します。さらに、プロキシおよびコンソールアプリケーションの作成方法についても説明します。

Step 1−サービスがIISでホストされたら、クライアントアプリケーションでそれを利用する必要があります。クライアントアプリケーションを作成する前に、サービスのプロキシを作成する必要があります。このプロキシは、クライアントアプリケーションがサービスと対話するために使用します。プロキシを作成するには、Visual Studio2008コマンドプロンプトを実行します。サービスユーティリティを使用して、プロキシクラスとその構成情報を作成できます。

svcutilhttp://localhost/IISHostedService/Service.svc

このコマンドを実行すると、デフォルトの場所に2つのファイルが生成されます。

  • MyService.cs −WCFサービスのプロキシクラス

  • output.config −サービスに関する構成情報

Step 2 −ここで、Visual Studio 2008(クライアントアプリケーション)を使用してコンソールアプリケーションの作成を開始します。

Step 3−参照 'System.ServiceModel'を追加します。これはWCFのコアdllです。

Step 4 −プロキシクラスを作成します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyServiceClient {
   Class Program {
      Static void Main(string[] args) {
         // Creating Proxy for the MyService
         ServiceClient Client = newServiceClient();
         Console.WriteLine("Client calling the service...");
         Console.WriteLine("Hello Ram");
         Console.Read();
      }
   }
}

出力は次のように表示されます-

セルフホストのWCFサービスの利用

ここでは、セルフホストのWCFサービスを利用するプロセス全体を、必要に応じて十分なコーディングとスクリーンショットとともに段階的に説明します。

Step 1−サービスがホストされているので、クライアントのプロキシクラスを実装する必要があります。プロキシを作成するにはさまざまな方法があります。

  • SvcUtil.exeを使用して、エンドポイントを使用してプロキシクラスとその構成ファイルを作成できます。

  • クライアントアプリケーションへのサービス参照の追加。

  • ClientBase <T>クラスの実装

これら3つの方法のうち、ClientBase <T>の実装がベストプラクティスです。他の2つのメソッドを使用している場合は、サービスの実装に変更を加えるたびにプロキシクラスを作成する必要があります。ただし、これはClientBase <T>には当てはまりません。実行時にのみプロキシを作成するため、すべてを処理します。

この目的のために、System.ServiceModelとMyCalculatorServiceの参照を含む1つのプロキシクラスを作成します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using MyCalculatorService;

namespace MyCalculatorServiceProxy {
   // WCF create proxy for ISimpleCalculator using ClientBase
   Public class MyCalculatorServiceProxy : 
   ClientBase<ISimpleCalculator>,
   
   ISimpleCalculator {
      Public int Add(int num1, int num2) {
         //Call base to do funtion
         returnbase.Channel.Add(num1, num2);
      }
   }
}

次に、System.ServiceModelとMyCalculatorServiceProxyの参照を含む1つのコンソールアプリケーションを作成します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using MyCalculatorServiceProxy;

namespace MyCalculatorServiceClient {
   classProgram {
      Static void Main(string[] args) {
         MyCalculatorServiceProxy.MyCalculatorServiceProxy proxy = newMyCalculatorServiceProxy.MyCalculatorServiceProxy();
         
         Console.WriteLine("Client is running at " + DateTime.Now.ToString());
         Console.WriteLine("Sum of two numbers. 5 + 5 =" + proxy.Add(5,5));
         Console.ReadLine();
      }
   }
}

Step 2 −エンドポイント(サービスと同じ)情報をクライアントアプリケーションの構成ファイルに追加する必要があります。

<?xmlversion = "1.0"encoding = "utf-8" ?>
<configuration>
   <system.serviceModel>
      <client>
         <endpoint address 
            ="http://localhost:8090/MyCalculatorServiceProxy/ISimpleCalculator"
            binding = "wsHttpBinding" contract "MyCalculatorServiceProxy.ISimpleCalculator">
            </endpoint>
      </client>
   </system.serviceModel>
</configuration>

Step 3−クライアントアプリケーションを実行する前に、サービスを実行する必要があります。以下に示すのは、クライアントアプリケーションの出力です。

WASでホストされているWCFサービスの使用

WASでホストされているWCFサービスの使用は、わずか数ステップの単純なプロセスです。手順は次のとおりです-

  • プロキシクラスと構成ファイルをクライアントアプリケーションに追加します。
  • MathServiceClientのオブジェクトを作成し、メソッドを呼び出します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespaceWASHostedClient {
   classProgram {
      staticvoid Main(string[] args) {
         MathServiceClient client = newMathServiceClient();
         Console.WriteLine("Sum of two number 5,6");
         Console.WriteLine(client.Add(5, 6));
         Console.ReadLine();
      }
   }
}

以下のような出力が表示されます。

WindowsサービスでホストされているWCFサービスの使用

WindowsサービスでホストされているWCFサービスを利用する方法のステップバイステップのプロセスを、コーディングと手順とともに以下に詳しく説明します。

正常にホストされたら、サービスのプロキシクラスを作成し、クライアントアプリケーションで使用を開始できます。ここでは、IISホスティングタイプが消費されている状態で示されています。

ServiceModelの参照を追加します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespaceWindowServiceClient {
   classProgram {
      staticvoid Main(string[] args) {
         //Creating Proxy for the MyService
         MyServiceClient client = newMyServiceClient();
         Console.WriteLine("Client calling the service...");
         Console.WriteLine("Sum of two numbers 5,6");
         Console.WriteLine(client.Add(5, 6));
        
         Console.WriteLine("Subtraction of two numbers 6,5");
         Console.WriteLine(client.Sub(6, 5));
        
         Console.WriteLine("Multiplication of two numbers 6,5");
         Console.WriteLine(client.Mul(6, 5));
        
         Console.WriteLine("Division of two numbers 6,3");
         Console.WriteLine(client.Div(6, 3));
         Console.Read();
      }
   }
}

出力は次のように表示されます-

WCFサービスバインディングはいくつかの要素のセットであり、各要素はサービスがクライアントと通信する方法を定義します。トランスポート要素とメッセージエンコーディング要素は、各バインディングの2つの最も重要なコンポーネントです。この章では、一般的に使用されるさまざまなWCFサービスバインディングについて説明します。

基本的なバインディング

基本的なバインディングは、BasicHttpBindingクラスによって提供されます。HTTPプロトコルを使用してWCFサービスをASP.NETWebサービス(ASMX Webサービス)として転送および表現するため、ASMXWebサービスを使用する古いクライアントは新しいサービスを便利に利用できます。

基本バインディングは、Silverlightによって有効化されたWCF Webサービスのデフォルトのバインディングとして設定されており、Webサービススタイルの通信の標準バインディングです。信頼できるメッセージングは​​サポートしていません。

以下に示すのは、基本的なバインディングのデフォルト設定を示すコードスニペットです。

<basicHttpBinding>
   <binding name = "basicHttpBindingDefaults" allowCookies = "false" 
      bypassProxyOnLocal = "false" hostNameComparisonMode = "StrongWildcard" 
      maxBufferPoolSize = "524288" maxBufferSize = "65536" 
      maxReceivedMessageSize = "65536" messageEncoding = "Text" proxyAddress = "" 
      textEncoding = "utf-8" transferMode = "Buffer" useDefaultWebProxy = "true" 
      closeTimeout = "00:01:00" openTimeout = "00:01:00" receiveTimeout = "00:10:00" 
      sendTimeout = "00:01:00">
   
      <readerQuotas maxArrayLength = "16384" maxBytesPerRead = "4096" 
         maxDepth = "32"
         maxNameTableCharCount = "16384" maxStringContentLength = "8192"/>

      <security mode = "None">
         <transport clientCredentialType = "None" proxyCredentialType = "None" realm = ""/>
         <message algorithmSuite = "Basic256" clientCredentialType = "UserName" />
      </security>       
   </binding>

</basicHttpBinding>

上記のデフォルト設定には、メッセージサイズが制限されており、セキュリティモードがないため、明らかな制限があります。ただし、基本的なバインディングをカスタマイズすると、次のようなこの問題が解決されます。

<basicHttpBinding>
   <binding name = "basicHttpSecure" maxBufferSize = "100000" maxReceivedMessageSize = "100000">
   
      <readerQuotas maxArrayLength = "100000" maxStringContentLength = "100000"/>
      <security mode = "TransportWithMessageCredential" />
     
   </binding>
</basicHttpBinding>

Webサービスバインディング

Webサービス(WS)バインディングは、WSHttpBindingクラスによって提供されます。これは基本的なバインディングと非常によく似ており、トランスポートに同じプロトコルを使用しますが、WS-Reliable Messaging、WS-Transactions、WS-SecurityなどのいくつかのWS- *仕様を提供します。一言で言えば、WSHttpBindingはbasicHttpBindingとWS– *仕様の合計に等しくなります。以下に示すのは、WSバインディングのデフォルト設定を示すコードスニペットです。

<wsHttpBinding>
   <binding name = "wsHttpBindingDefaults" allowCookies = "false" 
      bypassProxyOnLocal = "false" closeTimeout = "00:01:00" 
      hostNameComparisonMode = "StrongWildcard" 
      maxBufferPoolSize = "524288" maxReceivedMessageSize = "65536" 
      messageEncoding = "Text" openTimeout = "00:01:00" 
      receiveTimeout = "00:10:00" proxyAddress = "" sendTimeout = "00:01:00" 
      textEncoding = "utf-8" transactionFlow = "false" 
      useDefaultWebProxy = "true" > 
   
      <readerQuotas maxArrayLength = "16384" maxBytesPerRead = ."4096" 
         maxDepth = "32" maxNameTableCharCount = "16384" 
         maxStringContentLength = "8192"/>

      <reliableSession enabled = "false" ordered = "true" 
         inactivityTimeout = "oo:10:00" /> 

      <security mode = "Message">
         <message algorithmSuite = "Basic256" clientCredentialType = "Windows" 
            esatalishSecurityContext = "true" 
            negotiateServiceCredential = "true" />

         <transport clientCredentialType = "Windows"
            proxyCredentialType = "None" realm = ""/>        	
      </security>
      
   </binding>
</wsHttpBinding>

IPCバインディング

IPCバインディングは名前付きパイプを利用し、netNamedPipeBindingクラスによって提供されます。これは、利用可能なすべてのバインディングの中で最も高速なバインディングであり、最も安全なバインディングです。ここではメッセージレベルのセキュリティはサポートされていませんが、堅牢なトランスポートセキュリティにより、メッセージはデフォルトで安全です。以下に示すのは、IPCバインディングのデフォルト設定を示すコードスニペットです。

<netNamedPipeBinding>
   
   <binding name = "netPipeDefaults" closeTimeout = "00:01:00" 
      hostNameComparisonMode = "StrongWildcard" maxBufferPoolSize = "524288" 
      maxBufferSize = "65536" maxConnections = "10" 
      maxReceivedMessageSize = "65536" openTimeout = "00:01:00" 
      receiveTimeout = "00:10:00" sendTimeout = "00:01:00" transactionFlow = "false" 
      transactionProtocol = "OleTransactions" transferMode = "Buffered">  

      <readerQuotas maxArrayLength = "16384" maxBytesPerRead = "4096" 
         maxDepth = "32" maxNameTableCharCount = "16384" 
         maxStringContentLength = "8192"/>
   
      <security mode = "Transport">        	
      </security>
      
   </binding>
</netNamedPipeBinding>

他のタイプのサービスバインディング

  • TCP Binding− NetTCPBindingクラスによって提供されるこのバインディングは、同じネットワーク内の通信にTCPプロトコルを利用し、バイナリ形式でメッセージのエンコードを行います。このバインディングは、他のバインディングとは対照的に最も信頼できると見なされています。

  • WS Dual Binding−このタイプのバインディングは、双方向通信を容易にするという唯一の例外を除いて、WSHttpBindingに似ています。つまり、メッセージはクライアントとサービスの両方で送受信できます。これは、WSDualHttpBindingクラスによって提供されます。

  • Web binding − Webバインディングは、HTTP-GET、HTTP-POSTなどを使用してHTTP要求の形式でWCFサービスを表すように設計されています。これはWebHttpBindingクラスによって提供され、ソーシャルネットワークで一般的に使用されます。

  • MSMQ Binding− NetMsmqBindingクラスによって提供され、サービスがクライアントから送信された時間とは異なる時間にメッセージを処理する場合のソリューションを提供するために使用されます。MSMQバインディングは、転送にMSMQを利用し、キューに入れられた切り離されたメッセージをサポートします。MSMQは、Microsoftが提供するメッセージキューの実装です。

  • Federated WS Binding−これはWSバインディングの特定の形式であり、フェデレーションセキュリティのサポートを提供します。これは、WSFederationHttpBindingクラスによって提供されます。

  • Peer Network Binding− NetPeerTCPBindingクラスによって提供され、主にファイル共有システムで使用されます。TCPプロトコルを使用しますが、トランスポートとしてピアネットワークを利用します。このネットワークでは、各マシン(ノード)が他のノードのクライアントおよびサーバーとして機能します。ピアネットワークバインディングは、トレントなどのファイル共有システムで使用されます。

  • MSMQ Integration Binding − MsmqIntegrationBindingクラスによって提供され、MSMQ(Microsoft Message Queuing)を介して通信する既存のシステムとの通信を支援します。

これらとは別に、カスタムバインディングを作成することもできます。ただし、各WCFバインディングの構成プロパティを微調整できるため、カスタムバインディングを作成する必要が生じることはめったにありません。

メッセージ(クライアント要求)のセットをサービスインスタンスにバインドするためにWCFが採用する一連の手法は、インスタンス管理と呼ばれます。WCFは、3種類のインスタンスのアクティブ化をサポートしており、この章で説明します。

通話ごとのサービス

コールごとのサービスは、WCFのデフォルトのインスタンスアクティベーションモードです。WCFサービスが呼び出しごとのサービス用に構成されている場合、クライアントの呼び出しまたは要求が進行中の期間にCLRオブジェクトが作成されます。CLRはCommonLanguage Runtimeの略で、WCFのサービスインスタンスが含まれています。

呼び出しごとのサービスでは、すべてのクライアント要求が新しい専用サービスインスタンスを実現し、そのメモリ消費量は他のタイプのインスタンスアクティベーションと比較して少なくなります。

WCFサービスが呼び出しごとのサービスとして機能することを示すには、InstanceContextModeプロパティをInstanceContextMode.PerCallに設定する必要があります。InstanceContextModeプロパティは、ServiceBehavior属性に属しています。したがって、コールごとのサービスは次のように構成できます。

[ServiceContract]
interface IMyContract
{...}
[ServiceBehavior (InstanceContextMode = InstanceContextMode.PerCall)]
class MyService : IMyContract
{...}

ここでは、サービスはIMyContractとして表されます。次の図は、コールごとのサービスインスタンスのアクティブ化のプロセスを示しています。

通話ごとのサービスの実装

[DataContract]
class Param {....}

[ServiceContract]
interface IMyContract {
   [OperationContract]
   void MyMethod(Param objectIdentifier);
}
class MyPerCallService : IMyContract, IDisposable {
   public void MyMethod(Param objectIdentifier) {
      GetState(objectIdentifier); 
      DoWork();
      SaveState(objectIdentifier);
   }
   
   void GetState(Param objectIdentifier) {....}
   void DoWork() {....}
   void SaveState(Param objectIdentifier) {....}
   public void Dispose() {....}
}

ここで、Paramは、上記の例のために考案された疑似型パラメーターです。

セッションごとのサービス

WCFのこのアクティベーションモードでは、プライベートセッションまたは機密セッションが2つのエンティティ、つまりクライアントと特定のサービスインスタンスの間で維持されていると言えます。プライベートセッションサービスとも呼ばれるセッションごとのサービスは、各クライアントリクエスト専用であり、そのセッション対応サービスに関連する他のすべてのインスタンスから独立した新しいサービスインスタンスを提供します。

セッションごとのサービスを開始するには、InstanceContextModeプロパティをPerSessionに設定する必要があります。ここで、サービスインスタンスは、セッション期間中ずっとメモリに残ります。

この専用サービスインスタンスのそれぞれに関連するコストのために、構成されたサービスが少数(または最大で数百)以外の追加の未処理のクライアントをサポートできないため、アクティベーションモードはスケーラビリティに悩まされます。

セッションごとのサービスは、次のように構成できます。

[ServiceBehavior (InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract
{...}

セッションごとのサービスのプロセスは、次の図に示すように説明できます。

次のコードは、プライベートセッションの使用のために構成されたコントラクトとサービスを示しています。出力は、クライアントが実際に専用のサービスインスタンスを取得したことを示しています。

サービスコード

[ServiceContract(Session = true)]
interface IMyContract {
   [OperationContract]
   void MyMethod();
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract, IDisposable {
   int m_Counter = 0; MyService() {Console.WriteLine("MyService.MyService()"); }
   
   public void MyMethod() {
      m_Counter++;
      Console.WriteLine("Counter = " + m_Counter);
   }
   public void Dispose() { 
      Console.WriteLine("MyService.Dispose()"); 
   }
}

クライアントコード

MyContractProxy proxy = new MyContractProxy(); proxy.MyMethod(); proxy.MyMethod(); 
proxy.Close();

出力

MyService.MyService() Counter = 1 Counter = 2 MyService.Dispose()

シングルトンサービス

このWCFのアクティブ化モードでは、サービスエンドポイントへの接続に関係なく、互いに独立したすべてのクライアント要求が同じ既知の単一インスタンスに接続されます。シングルトンサービスは、ホストがシャットダウンしたときにのみ破棄されます。

このサービスは、ホストの作成時に1回だけ作成されます。ホストにシングルトンインスタンスが提供されていない場合、サービスはNULLとして返されます。アクティベーションモードは、各メソッド呼び出しの作業量が少なく、バックグラウンドで保留中の操作がない場合に最適です。

このシングルトンサービスを開始するには、InstanceContextModeプロパティをInstanceContextMode.Singleに設定する必要があります。

したがって、シングルトンサービスは次のように構成できます。

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class MySingleton : ...
{...}

シングルトンサービスのプロセスを次の図に示します-

次のコードは、シングルトンインスタンスの初期化とホストに使用されます。

サービスコード

[ServiceContract]
interface IMyContract {
   [OperationContract]
   void MyMethod( );
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class MySingleton : IMyContract {
   int m_Counter = 0;
   
   public int Counter {
      get {
         return m_Counter;
      }
      set {
         m_Counter = value;
      }
   }
   public void MyMethod( ) {
      m_Counter++;
      Trace.WriteLine("Counter = " + Counter);
   }
}

ホストコード

MySingleton singleton = new MySingleton( );
singleton.Counter = 42;
ServiceHost host = new ServiceHost(singleton);
host.Open( );

//Do some blocking calls then
host.Close( );

クライアントコード

MyContractClient proxy = new MyContractClient( );
proxy.MyMethod( );
proxy.Close( );

出力

Counter = 43

WCFのトランザクションは、ACIDと総称されるいくつかのプロパティに従う一連の操作です。ここで、1つの操作が失敗すると、システム全体が自動的に失敗します。オンラインで注文すると、トランザクションが発生します。次の例は、トランザクションのプロセスを簡単に理解するのに役立ちます。

オンラインストアに液晶テレビを注文し、その金額をクレジットカードで支払うとします。注文に必要な情報を入力すると、2つの操作が同時に発生します。

1つは、指定された金額が銀行口座から引き落とされること、もう1つは、ベンダーアカウントに同じ金額が入金されることです。トランザクションを成功させるには、両方の操作を正常に実行する必要があります。

WCFトランザクションプロパティ

WCFトランザクションが続く4つのプロパティは次のとおりです。

  • Atomic −すべての操作は、トランザクションの完了時に単一の分割できない操作として機能する必要があります。

  • Consistency −操作セットが何であれ、システムは常に一貫性のある状態にあります。つまり、トランザクションの結果は常に期待どおりです。

  • Isolation −トランザクションが完了するまで、システムの中間状態は外界のどのエンティティにも表示されません。

  • Durability −あらゆる種類の障害(ハードウェア、停電など)に関係なく、コミット状態が維持されます。

WCFトランザクションを構成する際、考慮が必要な要素がいくつかあります。これらはバインディングと操作の動作です。

Binding− WCFでトランザクションをサポートするバインディングはごくわずかであり、これらのバインディングのみから選択することが重要です。これらのバインディングはデフォルトで無効のままであり、トランザクションに必要なサポートを取得するには有効にする必要があります。これらのバインディングは次のとおりです-

  • NetTcpBinding
  • NetNamedPipeBinding
  • WSHttpBinding
  • WSDualHttpBinding
  • WSFederationHttpBinding

Operation behavior−バインディングはトランザクション伝播のパスを容易にしますが、オペレーションはトランザクション処理とオペレーション構成を処理します。操作動作は主に、TransactionFlowとTransactionScopeRequiredの2つの属性を使用します。ここで、TransactionFlowには主に3つの値があり、これらはAllowed、Mandatory、およびNotAllowedであることに注意してください。

次のコードは、バインディングと操作コントラクトの構成を変更すると、クライアントの伝播が容易になるかどうかを示しています。

<bindings> 
   <wsHttpBinding> 
      <binding name = "MandatoryTransBinding" transactionFlow = "true"> 
         <reliableSession enabled ="true"/>
      </binding>
   </wsHttpBinding> 
</bindings>

トランザクションプロトコル

WCFは、トランザクションに3種類のプロトコルを使用します-

  • Lightweight
  • オレ取引
  • WS-アトミックトランザクション(WS-AT)

3つすべてのうち、WS-ATは相互運用可能なプロトコルであり、ファイアウォールを越えた分散トランザクションのフローを可能にします。ただし、トランザクションが厳密にMicrosoftテクノロジに基づいている場合は、このプロトコルを使用しないでください。

WCFトランザクションのフェーズ

次の図に示すように、WCFトランザクションには2つのフェーズがあります。

  • Prepare Phase −このフェーズでは、トランザクションマネージャは、すべてのエンティティがトランザクションをコミットする準備ができているかどうかを確認します。

  • Commit Phase −このフェーズでは、エンティティのコミットメントが実際に開始されます。

次の図は、WCFトランザクションの両方のフェーズの機能を示しています。

WCFトランザクションの有効化

WCFトランザクションを正常に有効にするには、一連の6つの手順を順番に実行する必要があります。必要な手順については、以下で説明します。

Step 1 − Creation of two WCF Services

この点での最も重要なステップは、WCFで2つのサービスプロジェクトを構築して、単一のトランザクションに参加することです。データベーストランザクションはこれらのサービスの両方で実行され、WCFトランザクションによってどのように統合されるかが理解されます。WCFTransactionsのWebアプリケーションも作成され、作成された2つのサービスを単一のトランザクションスコープで使用します。

Step 2 − Method creation and its attribution with TransactionFlow attribute

ここでは、両方のWCFサービスがOperationContract属性を使用してデータベースに挿入するためのUpdateDataメソッドが作成されます。このタスクを実行するには、最初にServiceContract属性を使用してインターフェイスクラスを作成します。新しく作成されたメソッドでトランザクションを有効にするには、TransactionFlowに関連付けられ、isAllowed値を使用してトランザクションが許可されます。

[ServiceContract]
public interface IService1 {
   [OperationContract]
   [TransactionFlow(TransactionFlowOption.Allowed)]
   void UpdateData();
}

Step 3− Implementation of WCF service with TransactionScopeRequired attribute

以下に示すコードを使用して実行されます-

[OperationBehavior(TransactionScopeRequired = true)]
public void UpdateData() {
   try {
      SqlConnection objConnection = new SqlConnection(strConnection);
      objConnection.Open();
      
      using(SqlTransaction transaction = Program.dbConnection.BeginTransaction()) {
     	   Boolean doRollback = false;
     	   using(SqlCommand cmd = new SqlCommand(
            "insert into Customer (Customer name, Customer code) values ('sss', 'sss')"objConnection))
         
     	   try {
            cmd.ExecuteNonQuery();
     	   } catch(SqlException) {
            doRollback = true;
            break;
     	   }
      }
      
      if(doRollback)
         transaction.Rollback();
      else
         transaction.Commit();  
   }
   finally {
      objConection.Close();
   }
}

Step 4 − Enabling Transaction Flow by WCF Service Config File

そのコーディングは次のように行われます-

<bindings>
   <wsHttpBinding>
      <binding name = "TransactionalBind" transactionFlow = "true"/>
   </wsHttpBinding>
</bindings>

WCFサービスを公開するには、トランザクション許容バインディングをエンドポイントにアタッチすることが重要です。

<endpoint address = "" binding = "wsHttpBinding" bindingConfiguration = "TransactionalBind" contract = "WcfService1.IService1">

Step 5 − Calling both the services in a single transaction

ここでは、上記の2つのサービスが1つのトランザクションで呼び出され、この目的のために、TransactionScopeオブジェクトを使用して両方のサービスがグループ化されます。上記のオブジェクトのCompleteメソッドは、WCFトランザクションをコミットするために呼び出されます。ロールバックするには、Disposeメソッドを呼び出します。

using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew)) {
   try {
      // Call your webservice transactions here
      ts.Complete();
   } catch (Exception ex) {
      ts.Dispose();
   }
}

WCFトランザクションが1つのスコープにグループ化された完全なコードの小さな部分を以下に示します-

using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew)) {
   try {
      ServiceReference1.Service1Client obj = newServiceReference1.Service1Client();
      obj.UpdateData();
      ServiceReference2.Service1Client obj1 = new ServiceReference2.Service1Client();
      obj1.UpdateData();
      ts.Complete();
   } catch (Exception ex) {
      ts.Dispose();
   }
}

Step 6 − Testing WCF transaction

テストは6番目の最後のステップで実行され、最初のWCFサービスを呼び出した後、例外が強制されます。

WCF RIAサービスは、高レベルのフレームワークであり、.NET4やSilverlight4などのフレームワークの新しいコンポーネントであり、クライアント側の検証を提供することで、Silverlightで複雑なビジネスアプリケーションを構築する手順を容易にします。RIAはリッチインターネットアプリケーションの略です。

ここで、SilverlightはMicrosoftが提供するフレームワークであり、リッチインターネットアプリケーションに最適であり、AdobeFlashと同様にブラウザープラグインとして使用できることに注意する必要があります。

WCF RIAサービスは、主にWCFサービスの標準バージョンに基づいています。次の図は、WCFRIAサービスが一般的に焦点を当てているWCFアーキテクチャの一部を示しています。

WCF RIAサービスの作成は、概念をよりよく理解するための次のステップです。ステップバイステップの手順を以下に示します。

Step 1 − Silverlight 5を使用してSLWCFRiaServices.Webという名前の新しいWebプロジェクトを作成し、同じものにADO.NETエンティティデータモデルを選択して新しいアイテムを追加します。

Step 2 −データベースからモデルを生成して、エンティティデータモデルウィザードからモデルの内容を選択します。

Step 3 −同じウィザードから、データ接続とデータベースオブジェクトを選択します。

Step 4 −将来、データモデルの認識が、作成するドメインサービスにとって問題にならないようにソリューションを構築します。

Step 5 −新しいアイテムを追加して、Webプロジェクトにドメインサービスを作成し、クライアントアクセスを有効にしてください。

Step 6 −次のステップでは、いくつかのクラスが生成され、それらを再構築することが不可欠です。

Step 7 −このステップでは、DataDomainContextがデータソースパネルに表示されます。

Step 8 −このステップでは、DataDomainContextの下の記事を選択してカスタマイズする必要があります。

Step 9− DataGridコントロールをデータソースにアタッチすることは、テーマの選択とともに、ここでコミットされるステップです。ここでは、BureauBlueテーマが選択されています。

Step 10−最後の最後のステップは、デザイン画面に移動し、単純なドラッグアンドドロップでMainPageのレイアウト領域にエンティティを追加することです。AutoGenerateColumns = "True"を確認し、それを実行して出力を表示することも重要です。

前提条件

WCF RIAサービスの可能性を最大限に活用するには、いくつかの前提条件があります-

  • Visual Studio 2010 / Visual Studio 2012
  • Silverlight開発者ランタイム
  • RIAサービスツールキットの最新バージョン
  • SDK(ソフトウェア開発キット)

WCFRIAドメインサービス

ドメインサービスは、ビジネスに関連する一連のデータ操作で構成されます。これは、WCFRIAサービスアプリケーションのビジネスロジックを公開するWCFサービスに他なりません。

WCF RIAドメインサービスには、内部にホスティングクラスDomainServiceHostがあり、これは、アプリケーションをホストするためにWCFServiceHostクラスを使用します。クライアントプロジェクトがドメインサービスにアクセスできるようにするには、EnableClientAccessAttribute属性が必要です。この属性は、新しいドメインサービスクラスが追加されるたびに自動的に適用されます。

次の図は、WCFRIAドメインサービスのアーキテクチャを示しています-

WCF RIAサービス–データのクエリ

次の図は、クエリがクライアント側で作成され、サーバー側で実行されてクエリ可能な結果を​​返す方法を示しています。DALはデータアクセス層の略です。

WCF RIAサービス–データの更新

次の図は、サーバー側でCUD(Create Update Delete)操作を実行してデータを更新する方法を示しています。ここで、WCFRIAサービスはサーバー側では常にステートレスであることに注意してください。

WCFサービスは、目的のクライアントのみがサービスにアクセスできるように、2つのセキュリティモードまたはレベルを備えた堅牢なセキュリティシステムを誇っています。分散トランザクションで一般的なセキュリティの脅威は、WCFによって大幅に緩和されます。

主なセキュリティ機能

次の図に示すように、WCFサービスには4つの主要なセキュリティ機能があります。

  • Authentication −ここで、認証はメッセージの送信者を識別することに限定されず、相互に行われます。つまり、あらゆる種類の中間者攻撃の可能性を排除するために、メッセージ受信者の認証が必要です。

  • Authorization−これは、セキュリティを確保するためにWCFサービスが実行する次のステップであり、ここで、サービスが呼び出し元に続行を許可するかどうかを決定します。承認は認証に依存しませんが、通常は認証に従います。

  • Confidentiality−発信者とサービスの間の情報交換は、メッセージが意図されていない他の人による解釈を制限するために機密に保たれます。これを可能にするために、暗号化は他のさまざまなメカニズムとともに使用されます。

  • Integrity −最後の重要な概念は、整合性を維持することです。つまり、送信者から受信者への移動中にメッセージがだれによっても改ざんされていないことを保証します。

転送セキュリティモード

WCFは、クライアントとサーバー間の安全な通信を確保するために、次の転送セキュリティモードを提供します。さまざまな転送セキュリティモードを以下に示します。

  • None−このモードは、いかなる種類のメッセージセキュリティも保証せず、サービスはクライアントに関する資格情報を取得しません。このモードは、メッセージの改ざんを許可する可能性があるため、お勧めできないため、非常に危険です。

<wsHttpBinding>
   <binding name = "WCFSecurityExample">
      <security mode = "None"/>
   </binding>
</wsHttpBinding>
  • Transport−このモードは、TCP、IPC、Https、MSMQなどの通信プロトコルを使用してメッセージの安全な転送を実現する最も簡単な方法です。このモードは、転送がポイントツーポイントであり、主に制御された環境、つまりイントラネットアプリケーションで使用される場合に、より効果的です。

<wsHttpBinding>
   <binding name = "WCFSecurityExample">
      <security mode = "Transport"/>
   </binding>
</wsHttpBinding>
  • Message−セキュリティモードは相互認証を可能にし、メッセージが暗号化され、安全なプロトコルとは見なされないhttpを介して転送できるため、プライバシーを大幅に提供します。ここでは、メッセージ転送に関与する仲介者の数や、セキュリティで保護されたトランスポートがあるかどうかを考慮せずに、セキュリティがエンドツーエンドで提供されます。このモードは通常、インターネットアプリケーションで使用されます。

<wsHttpBinding>
   <binding name = "WCFSecurityExample">
      <security mode = "Message"/>
   </binding>
</wsHttpBinding>
  • Mixed −このセキュリティモードは頻繁には使用されず、クライアント認証はクライアントレベルでのみ提供されます。

<wsHttpBinding>
   <binding name = "WCFSecurityExample">
      <security mode = "TransportWithMessageCredential"/>
   </binding>
</wsHttpBinding>
  • Both−このセキュリティモードは、トランスポートセキュリティとメッセージセキュリティの両方で構成され、堅牢なセキュリティカバーを提供しますが、多くの場合、全体的なパフォーマンスが過負荷になります。これはMSMQでのみサポートされています。

<netMsmqBinding>
   <binding name = "WCFSecurityExample">
      <security mode = "Both"/>
   </binding>
</netMsmqBinding>

BasicHttpBindingを除くすべてのWCFバインディングには、デフォルトである程度の転送セキュリティがあります。

メッセージセキュリティレベル

メッセージレベルのセキュリティは、WCFプロトコルに依存しません。標準のアルゴリズムを使用してデータを暗号化することにより、メッセージデータ自体で使用されます。メッセージセキュリティレベルのさまざまなバインディングに使用できるクライアント資格情報がいくつかあります。これらについては、以下で説明します。

Client credentials for message level security in WCF

None−ここでは、メッセージを保護するために暗号化が使用されますが、クライアント認証は実行されません。つまり、匿名クライアントがサービスにアクセスできます。BasicHttpBindingを除いて、すべてのWCFバインディングはこのクライアント資格情報をサポートします。ただし、NetNamedPipeBindingの場合、このクライアント資格情報はまったく使用できないことに注意してください。

  • Windows−ここでは、メッセージの暗号化とクライアント認証の両方が、リアルタイムでログインしたユーザーに対して行われます。この場合も、他のすべてのWCFバインディングとは異なり、NetNamedPipeBindingは使用できず、BasicHttpBindingはサポートを提供しません。

  • UserName−ここでは、メッセージは暗号化され、ユーザー名を提供することで保護され、クライアントはパスワードを提供する必要があるときに認証されます。BasicHttpBindingは、上記の2つのクライアント資格情報と同様に、UserNameをサポートしておらず、NetNamedPipeBindingでは使用できません。

  • Certificate−メッセージの暗号化に加えて、クライアントとサービスの両方が証明書による認証を取得します。このクライアント資格情報は使用可能であり、NetNamedPipeBindingを除くすべてのWCFバインディングでサポートされています。

  • IssuedToken− Cardspaceなどの機関から発行されたトークンは、メッセージの認証に使用されます。メッセージの暗号化もここで実行されます。

次のコードは、クライアントの資格情報がWCFメッセージのセキュリティレベル/モードでどのように構成されているかを示しています。

<netTcpBinding>
   <binding name = "WCFMessageSecurityExample">
      <security mode = "Message">
         <message clientCredentialType = "None"/>
      </security>   
   </binding>
</netTcpBinding>

<netMsmqBinding>...</netMsmqBinding>
</bindings>
<behaviors>...</behaviors>

ここで、トランスポートセキュリティモードはメッセージセキュリティレベルよりも優れていることに注意する必要があります。前者の方が高速だからです。追加のコーディングを必要とせず、相​​互運用性のサポートを提供するため、全体的なパフォーマンスが低下することはありません。

ただし、セキュリティの観点から、メッセージセキュリティモードはより堅牢で、プロトコルに依存せず、エンドツーエンドのセキュリティを提供します。

WCFサービス開発者は、適切な方法でクライアントに報告する必要がある予期しないエラーに遭遇する可能性があります。として知られているそのようなエラーexceptions、通常はtry / catchブロックを使用して処理されますが、これもテクノロジー固有です。

クライアントの関心領域は、エラーの発生方法やエラーの原因となる要因ではないため、SOAP障害コントラクトを使用して、WCFでサービスからクライアントにエラーメッセージを伝達します。

フォールトコントラクトを使用すると、クライアントはサービスで発生したエラーを文書化して表示できます。次の例は、より良い理解を提供します。

Step 1 −一般的な例外を生成する除算操作で簡単な計算サービスが作成されます。

using System;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Runtime.Serialization;
usingSystem.ServiceModel;
usingSystem.Text;

namespace Calculator {
   // NOTE: You can use the "Rename" command on the "Refactor" menu to change 
   // the interface name "IService1" in both code and config file together.
   
   [ServiceContract]
   
   public interface IService1 {
      [OperationContract]
      int divide(int num1, int num2);
      // TODO: Add your service operations here
   }
}

クラスファイルのコーディングを以下に示します-

ここで、数値10をゼロで除算しようとすると、電卓サービスは例外をスローします。

例外は、try / catchブロックで処理できます。

ここで、任意の整数を0で除算しようとすると、catchブロックで処理したため、値10が返されます。

Step 2 −このステップでは、FaultExceptionを使用して、サービスからクライアントに例外情報を伝達します。

public int Divide(int num1, int num2) { 
   //Do something 
   throw new FaultException("Error while dividing number"); 
}

Step 3−FaultContractを使用してエラーメッセージを送信するカスタムタイプを作成することもできます。カスタムタイプを作成するために不可欠な手順を以下に示します-

タイプはデータコントラクトを使用して定義され、返されることを目的としたフィールドが指定されます。

サービス操作は、FaultContract属性によって装飾されます。タイプ名も指定されます。

例外を発生させるためにサービスインスタンスが作成され、カスタム例外プロパティが割り当てられます。