[VS2010] WCF 4.0 新功能 (1): 簡易組態 (Simple Configuration)
WCF (Windows Communication Foundation) 自.NET Framework 3.0 發布以來,歷經二次的大改版後,已經取代 .NET Remoting 以及 ASMX Services 成為微軟欽定的統一通訊 (Unified Communication) 開發平台,很多微軟的通訊平台都是利用 WCF 來開發的,它也悄悄的成為使用微軟開發平台的開發人員的重要關卡之一,未來在微軟平台上許許多多的伺服器與通訊架構都將要使用 WCF 來開發,Windows Azure AppFabric 的 Service Bus 就是其中一個最好的例子,但 WCF 學習曲線較陡的幾個地方,也是開發人員學習的瓶頸,像是協定繫結組態 (Protocol Binding Configuration) 就是其中的一個陡坡,在 WCF 中支援相當多的通訊協定,選擇是一回事,設定又是一回事,光是設定協定就已經令開發人員頭大,微軟也知道這點,在 WCF 4.0 中微軟將幾個常用的通訊協定,包裝成稱為標準終端點 (Standard Endpoint) 的封裝,這些封裝設定內建在標準通訊協定的程式碼中,因此使用這些協定的應用程式,將可大量簡化 WCF 應用程式的通訊設定,如此開發人員學習 WCF 4.0 的學習曲線便可降低一級。
有多簡單呢?舉例來說,下列一個簡單且使用 WCF 3.5 的應用程式的組態設定:
<system.serviceModel>
<bindings>
<!-- Application Binding -->
<wsHttpBinding>
<binding name="default” />
</wsHttpBinding>
</bindings>
<services>
<!-- Application Service -->
<service name="AppFabricSB_ProductService.ProductQuery"
behaviorConfiguration="default">
<endpoint name="Endpoint"
contract="AppFabricSB_ProductService.IProductQuery"
binding="wsHttpBinding"
bindingConfiguration="default"
behaviorConfiguration="sharedSecretClientCredentials"
address="" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="sharedSecretClientCredentials">
<transportClientEndpointBehavior credentialType="SharedSecret">
<clientCredentials>
<sharedSecret issuerName="owner" issuerSecret="ceSHrhkaqcqgN/suoV8j2Zte+9HJvlJexxJaWtjp0Mo=" />
</clientCredentials>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="default">
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
到了 WCF 4.0 時,組態設定變成只要這樣:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled ="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="wsHttpBinding" scheme ="http"/>
</protocolMapping>
</system.serviceModel>
有沒有變得很簡單呢?這就是 WCF Simple Configuration 的威力。
例如,下列的應用程式是一個使用 WCF 4.0 的範例程式碼 (專案類型為 Console Application,有加入 System.Runtime.Serialization.dll, System.ServiceModel.dll 與 System.ServiceModel.Web.dll 的參考):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
namespace SimpleConfiguration
{
[DataContract]
public class ProductInfo
{
[DataMember]
public int ProductID { get; set; }
[DataMember]
public string Name { get; set; }
}
[ServiceContract(Namespace = "http://sample.azure.com/appfabric/servicebus/productcontract")]
public interface IProductQuery
{
[OperationContract, WebGet]
List<ProductInfo> LookupProducts();
[OperationContract, WebGet]
ProductInfo LookupProduct(int ProductID);
}
[ServiceBehavior(Name = "ProductQuery", Namespace = "http://sample.azure.com/appfabric/servicebus/productqueryservice")]
public class ProductQuery : IProductQuery
{
public List<ProductInfo> LookupProducts()
{
List<ProductInfo> products = new List<ProductInfo>();
using (NorthwindEntities context = new NorthwindEntities())
{
var query = from q in context.Products
select q;
if (query.Count() > 0)
{
foreach (var item in query)
products.Add(new ProductInfo() { Name = item.ProductName, ProductID = item.ProductID });
}
}
return products;
}
public ProductInfo LookupProduct(int ProductID)
{
ProductInfo productInfo = new ProductInfo();
using (NorthwindEntities context = new NorthwindEntities())
{
var query = from q in context.Products
where q.ProductID == ProductID
select q;
if (query.Count() > 0)
{
productInfo.ProductID = query.First().ProductID;
productInfo.Name = query.First().ProductName;
}
}
return productInfo;
}
}
class Program
{
static void Main(string[] args)
{
WebServiceHost host = new WebServiceHost(typeof(ProductQuery), new Uri("http://localhost:8080/ProductQuery"));
host.Open();
Console.WriteLine("Press ENTER to stop this service.");
Console.ReadLine();
host.Close();
host = null;
}
}
}
以上程式碼皆只使用 WCF 的基本指令,沒有做什麼額外的設定,但重點是在 app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled ="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="wsHttpBinding" scheme ="http"/>
</protocolMapping>
</system.serviceModel>
<connectionStrings>
<add name="NorthwindEntities" connectionString="metadata=res://*/Northwind.csdl|res://*/Northwind.ssdl|res://*/Northwind.msl;provider=System.Data.SqlClient;provider connection string=…"
providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
編譯並建立執行檔,然後執行它,會看到這樣的畫面:
然後瀏覽 http://localhost:8080/ProductQuery/LookupProducts,可以看到這樣的結果:
參考資料: