WCF 4.0中的新特性:简化的配置

微软服务器与开发工具事业部 熊炜

自从WCF 问世以来, WCF服务的配置一直是广大开发人员所关心的话题。由于WCF作为一个通用服务框架,拥有大量的拓展点,您有时会觉得配置文件过于复杂。在WCF 4.0中,根据各方面收集的用户反馈,WCF团队对WCF的配置做了大量的简化工作,以方便您更快更好的配置WCF服务。下面会给大家主要介绍以下几点:

  • 缺省服务配置
  • 标准终结点(Standard Endpoint)
  • 简化的IIS/ASP.NET中的部署

1. 缺省服务配置

我们都知道,在WCF3.0或3.5中,对每一个服务我们都必须要详细地定义地址,绑定(binding),契约(contract),行为(behavior)等一系列的配置,缺一不可。而在WCF4.0中,配置文件中增加了许多缺省选项:从终结点,到绑定,各种行为,都可以被省略。下面是一个简单的WCF服务,运行这个服务甚至不需要配置文件:

namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

  using (ServiceHost host = new ServiceHost(typeof(Service1),

                                                      new Uri("https://localhost/Service1")))

            {

                host.Open();

                ServiceEndpoint endpoint = host.Description.Endpoints[0];

                Console.WriteLine("Address: {0}\nBinding: {1}", endpoint.Address, endpoint.Binding);

                Console.ReadLine();

            }

        }

    }

 

    [ServiceContract]

    class Service1

    {

        [OperationContract]

        public void DoWork()

        {

        }

    }

}

 

运行这个程序结果如下所示:

clip_image001

可以看到,虽然我们在程序中并没有添加终结点,也没有指定绑定,但WCF还是智能地为我们做了这两项配置,那WCF是通过怎样的机制来做这项设定的呢?

1.1.  缺省的终结点和绑定

事实上,WCF4.0框架会自动检测当前将要运行的服务的终结点个数。根据用户反馈,不少程序员会忘记往当前服务中添加终结点,结果自然是在服务运行的时候跳出错误。在4.0中,如果您指定了服务类型和服务的基本地址,WCF会用这个地址为您自动添加一个终结点。

我们同时可以看到,WCF为这个服务自动选定了BasicHttpBinding。是的,WCF会根据当前URI地址的前缀(在这里是https://),自动挑选对应的缺省绑定。下面是几个常见前缀的默认绑定表:

前缀

绑定

Http

BasicHttpBinding

Net.tcp

NetTcpBinding

Net.Pipe

NetNamedPipeBinding

 

值得注意的是,如果您为您的服务添加了两个不同的基本地址,WCF会为这两个地址分别添加一个终结点。如果这两个终结点地址的前缀不同的话,您就会自动拥有了两个不同绑定的终结点。

如果您希望改动这里的缺省绑定对应,比如,希望用WsHttpBinding来作为Http前缀的缺省绑定,您只需要在配置文件中添加如下语句:

  <system.serviceModel>

    <protocolMapping>

      <add scheme="http" binding="wsHttpBinding"/>

    </protocolMapping>

  </system.serviceModel>

如果您熟悉WCF ABC (Address,Binding,Contract)话一定会还有一个小疑问:那这边的契约是怎么定义的呢?相信大家一定能够想到,如果当前服务实现了多个WCF 服务接口,WCF会为每一个接口创建一个新的终结点。这边这些终结点会共用一个服务地址和绑定。由于彼此契约不同,这样的行为并不会引起任何冲突。

1.2. 默认的绑定/行为设定

在WCF3.0或3.5中,您需要为您的每一个绑定或者行为取一个名字,然后您的每个终结点需要指定某个定义好的绑定或行为来进行应用。可以想象,当您有几十个甚至几百个服务同时应用相同的绑定或行为的时候,指定这些名字将成为单纯的体力劳动。为了避免这样的情况,WCF4.0 引入了默认绑定/行为的设定。下面是一个默认绑定的例子:

  <system.serviceModel>

    <bindings>

      <wsHttpBinding>

        <binding>

          <security mode ="Message">

            <message clientCredentialType="UserName"/>

          </security>

        </binding>

      </wsHttpBinding>

    </bindings>

  </system.serviceModel>

 

请注意这边我们在定义绑定的时候并没有给这个绑定取名字!在WCF 3.0或3.5版本中是不合法的,但在4.0中,这样的行为表示默认设定。也就是说在当前配置文件中其他用到WsHttpBinding的服务,如果没有指定对应的绑定,那么就会自动采用这个默认绑定,即拥有采用用户名密码认证模式的消息级安全设定。这样的设定方式无疑能够大大的简化程序员的工作量。

WCF的默认行为设定和默认绑定设定的方式类似。同样,如果您在定义完您的服务级行为或者终结点级行为后不特别取一个名字,那么这个行为就能够直接为您所有没指定行为的服务或终结点所采用。

2. 标准终结点

在WCF 3.0或3.5中,为了能够暴露一个元数据端口(metadata endpoint),您也许常常需要采用如下的方式定义端口:

<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>

您会发现对于每个服务,元数据端口的设置其实基本上都是一致的,每次重复写同样的设定其实是没有必要的。因此在WCF 4.0中,我们将一些常用的终结点规范化,引入了一个“标准终结点”的概念。下面就是一个元数据端口的标准终结点的用法:

<endpoint address="mex" kind="mexEndpoint"/>

这里用新关键词“kind”直接指定了这个标准终结点的类型。可以看到这样的写法会为您省下不少工作,同时也减少了出错的可能。另外,和普通的终结点一样,您始终可以在配置文件中对标准终结点的各项设定做出您自己的修改。

下面是WCF4.0 中设定的标准终结点的列表,供您参考:

标准终结点的名字

描述

mexEndpoint

元数据终结点。采用IMetadataExchange 作为服务接口,mexHttpBinding 作为默认绑定。地址设定默认为空。

dynamicEndpoint

WCF 4.0中新引入的支持服务地址动态寻找的(WS-Discovery)客户端标准终结点。这个标准终结点不需要指定服务地址。当这个终结点第一次被调用时,它会自动根据当前指定的绑定和契约寻找符合要求的服务,并自动返回结果。

discoveryEndpoint

WCF 4.0中新引入的支持WS-Discovery的服务端标准终结点。使用这个终结点时用户需要指定绑定和契约。

udpDiscoveryEndpoint

WCF 4.0中新引入的支持WS-Discovery的服务端标准终结点。它主要支持基于UDP的服务发现机制。

announcementEndpoint

WCF 4.0中为了实现WS-Discovery标准中服务宣告功能而新引入的服务端标准终结点。

udpAnnouncementEndpoint

WCF 4.0中为了实现WS-Discovery标准中服务宣告功能而新引入的服务端标准终结点。它主要支持基于UDP的服务发现机制。

workflowControlEndpoint

为了工作流进程控制而设计的标准终结点,支持创建,运行,挂起,终结工作流等操作。

webHttpEndpoint

为了REST服务而设计的标准终结点。它默认采用WebHttpBinding和WebHttpBehavior。

webScriptEndpoint

为了Ajax服务而设计的标准终结点。它默认采用WebHttpBinding和WebScriptEnablingBehavior。

 

3. 简化的IIS/ASP.NET中的部署

WCF 4.0针对用户在IIS中的部署做了很多简化工作。如果您曾经在WCF 3.5中为ASP.NET项目添加一个WCF服务,那么先想象一下那时候您需要做的所有操作,然后看一下下面的添加一个WCF 4.0服务的例子:

Service1.svc:

<%@ ServiceHost Language="C#" Debug="true" Service="WcfService1.Service1" %>

 

namespace WcfService1

{

    using System.ServiceModel;

    [ServiceContract]

    public class Service1

    {

        [OperationContract]

        public void DoWork()

        {

        }

    }

}

如果您自己创建了一个ASP.NET项目并且添加了上述服务文件,您会发现:

- 您不再需要单独创建一个接口作为服务的契约了。

- 您可以直接把您的服务内容写在.svc文件里面,这样可以直接省下一个.svc.cs(或.vb)文件。

- 您甚至不需要改动Web.Config就能够使得这个服务自动运行。如果您的Web.Config中添加了支持元数据的默认行为,您的服务不需要任何额外设置就拥有了元数据服务支持。

如果您不喜欢用.svc文件而倾向于用.cs或者.vb文件来描述您的服务,您可以反其道而行之,在您的Web.Config文件中添加如下描述:

  <system.serviceModel>

    <serviceHostingEnvironment>

      <serviceActivations>

        <add relativeAddress="Service1.svc" service="WcfService1.Service1"/>

      </serviceActivations>

    </serviceHostingEnvironment>

  </system.serviceModel>

您可以在这一段中添加所有您的服务描述,在舍弃您所有冗余的.svc文件的同时,也使得您的所有服务有了一个统一的描述地点,管理起来更加方便,可谓一举两得。

是的,一切就那么简单!

4. 小结

以上为大家简单介绍了一下WCF 4.0中关于简化的配置的新特性。希望这些工作能够为您节省更多的时间,做出更好的产品。也希望能够得到您更多关于我们产品的反馈,以便于我们在下一个版本中做出更多的改进和优化。谢谢!