Implementing a Service Class
A service class is a class like any other, but it has a few
additions. These additions allow the class’s creator to define one or more
contracts that this class implements. Each service class implements at least
one service contract, which defines the operations this service exposes. The
class might also provide an explicit data contract, which defines the data
those operations convey.
Defining Service Contracts
·
Every
service class implements methods for its clients to use. The creator of the
class determines which of its methods are exposed as client-callable operations
by specifying that they are part of some service contract. To do this, a
developer uses the WCF-defined attribute ServiceContract. In fact, a service
class is just a class that either is itself marked with the ServiceContract
attribute or implements an interface marked with this attribute.
·
Namespace
used here is using System.ServiceModel;
Class
should be decorated as [ServiceContract] attribute
using System.ServiceModel;
[ServiceContract]
class RentalReservations
{
}
·
Each
method in a service class that can be invoked by a client must be marked with
another attribute named OperationContract. All the methods in a service class
that are preceded by the OperationContract attribute are automatically exposed
by WCF as services.
[ServiceContract]
class RentalReservations
{
[OperationContract]
public bool Check(int vehicleClass, int location,
string dates)
{
bool availability;
// code to check availability goes
here
return availability;
}
}
·
Any
methods in a service class that aren’t marked with OperationContract aren’t
included in the service contract, and so can’t be called by clients of this WCF
service.
·
It’s better
to specify service contracts explicitly using a language’s interface type. class
might look like this:
using
System.ServiceModel;
[ServiceContract]
interface IReservations
{
[OperationContract]
bool
Check(int vehicleClass, int location, string dates);
}
class RentalReservations
: IReservations
{
public bool
Check(int vehicleClass, int location,
string dates)
{
bool availability;
// logic to check availability goes here
return availability;
}
}
·
Using
explicit interfaces like this is slightly more complicated, but it allows more
flexibility. For example, a class can implement more than one interface, which
means that it can also implement more than one service contract. By exposing
multiple endpoints, each with a different service contract, a service class can
present different groups of services to different clients.
·
Marking
a class or interface with ServiceContract and one or more of its methods with
OperationContract also allows automatically generating service contract
definitions in WSDL. Accordingly, the externally visible definition of every
WCF service contract can be accessed as a standard WSDL document specifying the
operations in that contract. This style of development, commonly called
code-first, allows creating a standard interface definition directly from types
defined in programming languages such as C# or Visual Basic.
·
An
alternative approach is contract-first development, an option that WCF also
supports. In this case, a developer typically starts with a WSDL document
describing the interface (i.e., the contract) that a service class must
implement. Using a tool called svcutil, the developer can generate a skeleton
service class directly from a WSDL definition.
Defining Data Contracts
·
A WCF
service class specifies a service contract defining which of its methods are
exposed to clients of that service. Each of those operations will typically
convey some data, which means that a service contract also implies some kind of
data contract describing the information that will be exchanged. In some cases,
this data contract is defined implicitly as part of the service contract.
·
For
services where every operation uses only simple types, it makes sense to define
the data aspects of their contract implicitly within the service contract.
There’s no need for anything else.
·
But
services can also have parameters of more complex types, such as structures. In
cases like this, an explicit data contract is required. Data contracts define
how in-memory types are converted to a form suitable for transmission across
the wire, a process known as serialization. In effect, data contracts are a
mechanism for controlling how data is serialized.
·
In a
WCF service class, a data contract is defined using the DataContract attribute.
A class, structure, or other type marked with DataContract can have one or more
of its members preceded by the DataMember attribute, indicating that this
member should be included in a serialized value of this type.
using System.Runtime.Serialization;
[DataContract]
struct ReservationInfo {
[DataMember] public int vehicleClass;
[DataMember] public int location;
[DataMember] public string dates;
}
·
Nothing
becomes part of either a service contract or a data contract by default.
Instead, a developer must explicitly use the ServiceContract and DataContract
attributes to indicate which types have WCF-defined contracts, and then
explicitly specify which parts of those types are exposed to clients of this
service using the OperationContract and DataMember attributes. One of WCF’s
design tenets was that services should have explicit boundaries, so WCF is an
opt-in technology. Everything a service makes available to its clients is
expressly specified in the code.
No comments:
Post a Comment