[WCF] Contract

在 WCF 中,所有的服务都通过契约供外部进行调用。所谓契约,就是描述服务的一种平台无关的、标准的方式。目前,在 WCF 中定义了四种契约。

l         服务契约(Service contract)

描述了客户端能够调用服务的哪些操作。

l         数据契约(Data contract)

描述了哪些数据类型能够在客户端和服务间传输。CLR 数据类型都默认地被添加上了数据契约,当然也可以很方便的为自定义类型添加数据契约。

l         异常契约(Fault contract)

描述了在服务中可能出现的异常以及服务如何处理、传播异常。

l         消息契约(Message contract)

指定了该契约的消息能够直接与服务进行交互。

 

服务契约

using System;
using System.ServiceModel;

namespace Anrs.Service
{
    [ServiceContract()]
    
public interface IAnrsServiceContract
    {
        [OperationContract()]
        
string GetFullName(string author);

        [OperationContract()]
        
string GetFamilyName(string author);
    }

    
public class AnrsService : IAnrsServiceContract
    {
        
public string GetFullName(string author)
        {
            
return author.Replace('.'' ');
        }

        
public string GetFamilyName(string author)
        {
            
return author.Split('.')[2];
        }
    }
}

服务契约映射到 CLR 接口类型,并且对于契约来讲,可访问性是无关紧要的,因为“可访问性”本身就是一个 CLR 的概念,在 WCF 中是不存在该概念的。没有实现  ServiceContract 特性的接口对客户端就是不可见的,这就暗合了 SO 的“边界清晰”原则。另外,必须明确告诉 WCF 那些方法是 ServiceContract 的一部分(使用 OperationContract 特性,没有应用 OperationContract 特性的方法将不被视为服务契约的一部分),也就是说这些方法能够被客户端调用。不过,OperationContract 特性只能应用到方法上,对 properties/indexers/events 来讲都是无效的。

单个方法也可以实现多个应用了 ServiceContract 特性的接口。

using System;
using System.ServiceModel;

namespace Anrs.Service
{
    [ServiceContract()]
    
public interface IAnrsServiceContract1
    {
        [OperationContract()]
        
string GetFullName(string author);

        [OperationContract()]
        
string GetFamilyName(string author);
    }

    [ServiceContract()]
    
public interface IAnrsServiceContract2
    {
        [OperationContract()]
        
void SaveAuthor(string author);
    }

    
public class AnrsService : IAnrsServiceContract1, IAnrsServiceContract2
    {
        
public string GetFullName(string author)
        {
            
return author.Replace('.'' ');
        }

        
public string GetFamilyName(string author)
        {
            
return author.Split('.')[2];
        }

        
public void SaveAuthor(string author)
        {
            Console.WriteLine(
"Save {0} to database", author);
        }
    }
}
 

名字1和命名空间

可以也应该为 ServiceContract 定义一个命名空间(命名空间的好处就不用多说了),象下面这样:

[ServiceContract(Namespace="Anrs.Service")]
public interface IAnrsServiceContract1

如果没有明确指定命名空间,WCF 会为 ServiceContract 指定一个默认的命名空间 http://tempuri.org 。ServiceContract 的名字最好和接口的名字相同。

[ServiceContract(Namespace="Anrs.Service", Name="IAnrsServiceContract1")]
public interface IAnrsServiceContract1

同样的,也可以为 OperationContract 指定名字。

 

    [ServiceContract(Namespace="Anrs.Service", Name="IAnrsServiceContract1")]
    
public interface IAnrsServiceContract1
    {
        [OperationContract(Name
="GetFullName")]
        
string GetFullName(string author);

 

 

 

1. 为 ServiceContract/OperationContract 指定不同于 interface/method 实际名字的别名会影响到发送到客户端的元数据(metadata)。


posted on 2007-05-29 15:12  Anders x Hu  阅读(1759)  评论(1编辑  收藏  举报