使用代码和配置文件写一个WCF服务
WCF为在配置文件中定义服务属性提供了丰富的支持。你仍然需要为你将要在服务中暴露的特性或者算法编码,但是终结点地址,绑定和行为可以从代码中移动到配置文件中。
通过配置文件定义终结点和行为比通过代码更具扩展性。 举例说明,假设实现一个终结点并通过HTTP来通信。在列表1.1中,这是通过调用AddServiceEndpoint以及BasicHttpBinding 完成的。现在假设你将把绑定改为使用WSHttpBinding,通过在消息层面的处理将比在传输层面的处理带来更好的安全性能。在那种情况下,你需要改代码并需要重新编译它们。通过把绑定部分从代码移到配置文件中,可以让我们不必重新编译代码就实现改变。或者,你想在多于两种协议上暴露契约,你可以定义两个终结点: 一个使用基本HTTP另一个使用不用改变代码的WS-Security。这将使代码更加容易管理。
列表1.2 显示了寄宿在控制台应用程序中的一个WCF服务的完整代码。这个代码需要配置文件来定义行为和终结点信息。在这个例子中,我们主要做了以下工作。
定义契约。写一个.NET类并做一些有用的工作然后使用WCF属性修饰它。不管它通过代码还是配置文件暴露,在服务定义上都没有差别。列表1.2 中使用和列表1.1 中一样的StockService 类。
在一个操作系统进程中寄宿服务以便于它可以被客户端通过网络访问。这个通过调用在1.1 列表中的通过调用在System.ServiceModel 命名空间的ServiceHost 类创建的对象的Open方法来实现。
定义一个确定服务基地址和服务终结点ABCs的控制文件。注意在列表1.2 中的代码并不涉及配置文件。当ServiceHost.Open方法被调用时,WCF在应用程序配置文件中(app.config 或者web.config)寻找<servicemodel>来应用配置数据。
列表1.2 使用代码和配置文件实现服务
using System; using System.ServiceModel; namespace EssentialWCF { [ServiceContract] public interface IStockService { [OperationContract] double GetPrice(string ticker); } public class StockService : IStockService { public double GetPrice(string ticker) { return 94.85; } } public class Service { public static void Main() { ServiceHost serviceHost = new ServiceHost(typeof(StockService)); serviceHost.Open(); Console.WriteLine("Press <Enter> to terminate.\r\n"); Console.ReadLine(); serviceHost.Close(); } } }
列表1.3显示显示了与列表1.1中的代码一起工作的完整的配置文件。在ServiceModel部分,定义终结点。对每一个终结点,定义地址,绑定和契约。地址是空的,意味着终结点地址和服务的基地址一致。如果有超过一个终结点,每个终结点必须有一个独立的地址。在这个例子中的绑定是basicHttpBinding而且契约名就是源代码中类的名称,EssentialWCF.StockService.
列表1.3 实现一个服务的配置文件
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="EssentialWCF.StockService"> <host> <baseaddresses> <add baseaddress="http://localhost:8000/EssentialWCF" /> </baseaddresses> </host> <endpoint address="" binding="basicHttpBinding" contract="EssentialWCF.IStockService" /> </service> </services> </system.serviceModel> </configuration>