1.4. ContractsIn WCF, all services expose contracts. The contract is a platform-neutral and standard way of describing what the service does. WCF defines four types of contracts.
1.4.1. The Service ContractThe ServiceContractAttribute is defined as: [AttributeUsage(AttributeTargets.Interface|AttributeTargets.Class, Inherited = false)] public sealed class ServiceContractAttribute : Attribute { public string Name {get;set;} public string Namespace {get;set;} //More members } This attribute allows you to define a service contract. You can apply the attribute on an interface or a class, as shown in Example 1-1. Example 1-1. Defining and implementing a service contract
The ServiceContract attribute maps a CLR interface (or inferred interface, as you will see later on) to a technology-neutral service contract. The ServiceContract attribute exposes a CLR interface (or a class) as a WCF contract, independently of that type's visibility. The type visibility has no bearing on WCF, because visibility is a CLR concept. Applying the ServiceContract attribute on an internal interface exposes that interface as a public service contract, ready to be consumed across the service boundary. Without the ServiceContract attribute, the interface is not visible to WCF clients, in line with the service-oriented tenet that service boundaries are explicit. To enforce that, all contracts must explicitly opt in: only interfaces (or classes) decorated with the ServiceContract attribute will be considered as WCF contracts. Other types will not. In addition, none of the members of the type will ever be part of the contract when using the ServiceContract attribute. You must explicitly indicate to WCF which methods to expose as part of the WCF contract using the OperationContractAttribute, defined as: [AttributeUsage(AttributeTargets.Method)] public sealed class OperationContractAttribute : Attribute { public string Name {get;set;} //More members } You can only apply the OperationContract attribute on methods, but not on properties, indexers, or events, which are CLR concepts. WCF only understands operationslogical functionsand the OperationContract attribute exposes a contract method as a logical operation to perform as part of the service contract. Other methods on the interface (or class) that do not have the OperationContract attribute will not be part of the contract. This enforces the explicit service boundary and maintains an explicit opt-in model for the operations themselves. In addition, a contract operation cannot use object references as parametersonly primitive types or data contracts are allowed. 1.4.1.1. Applying the ServiceContract attributeWCF lets you apply the ServiceContract attribute on an interface or on a class. When you apply it on an interface, some class needs to implement the interface. In general, you use plain C# or VB to implement the interface, and nothing in the service class code pertains to it being a WCF service: [ServiceContract] interface IMyContract { [OperationContract] string MyMethod( ); } class MyService : IMyContract { public string MyMethod( ) { return "Hello WCF"; } } You can use implicit or explicit interface implementation: class MyService : IMyContract { string IMyContract.MyMethod( ) { return "Hello WCF"; } } A single class can support multiple contracts by deriving and implementing multiple interfaces decorated with the ServiceContract attribute. [ServiceContract] interface IMyContract { [OperationContract] string MyMethod( ); } [ServiceContract] interface IMyOtherContract { [OperationContract] void MyOtherMethod( ); } class MyService : IMyContract,IMyOtherContract { public string MyMethod( ) {...} public void MyOtherMethod( ) {...} } There are, however, a few implementation constraints on the service implementation class. You should avoid parameterized constructors because only the default constructor will ever be used by WCF. Also, although the class can use internal properties, indexers, and static members, no WCF client will ever be able to access them. WCF also lets you apply the ServiceContract attribute directly on the service class, without ever defining a separate contract first: //Avoid [ServiceContract] class MyService { [OperationContract] string MyMethod( ) { return "Hello WCF"; } } Under the covers, WCF will infer the contract definition. You can apply the OperationContract attribute on any method of the class, be it private or public.
1.4.1.2. Names and namespacesYou can and should define a namespace for your contract. The contract namespace serves the same purpose in WCF as it does in .NET programming: to scope a type of contract and reduce the overall chance for a collision. You use the Namespace property of the ServiceContract attribute to provide a namespace: [ServiceContract(Namespace = "MyNamespace")] interface IMyContract {...} Unspecified, the contract namespace defaults to http://tempuri.org. For outward-facing services you would typically use your company's URL, and for intranet services you can use any meaningful unique name, such as MyApplication. By default, the exposed name of the contract will be the name of the interface used. However, you could use an alias for a contract to expose a different name to the clients in the metadata using the Name property of the ServiceContract attribute: [ServiceContract(Name = "IMyContract")] interface IMyOtherContract {...} In similar manner, the name of the publicly exposed operation defaults to the method name, but you can use the Name property of the OperationContract attribute to alias it to a different publicly exposed name: [ServiceContract] interface IMyContract { [OperationContract(Name = "SomeOperation")] void MyMethod(string text); } You will see a use for these properties in the next chapter. |