Proxy Data Provider with WCF – Contract
Sunday, July 26, 2009 at 3:25PM This article is a continuation of a longer tutorial. If you haven’t done so already you should read it from the beginning.
Contract
The contract defines which operations the WCF Service provides. This is also the only assembly that both the client and server will have in common.
The WCF Data Provider is just a proxy on top of other data providers. This means that most of the methods will be close to a 1:1 mapping of the methods and properties in the ADO.Net data provider interfaces (IDbConnection, IDbCommand, etc).
There are a few things we need to take special note of in the contract.
10 [ServiceContract]
11 public interface IWcfDataProvider
12 {
13 #region IDbConnection
14 [OperationContract]
15 string CreateConnection(string invariantName);
16
17 [OperationContract]
18 void SetConnectionString(string token, string connectionString);
19
20 [OperationContract]
21 string GetConnectionString(string token);
22
23 [OperationContract]
24 void ChangeDatabase(string token, string databaseName);
25
26 [OperationContract]
27 void Close(string token);
28
29 [OperationContract]
30 int GetConnectionTimeout(string token);
31
32 [OperationContract]
33 string CreateCommand(string token);
34
35 [OperationContract]
36 string GetDatabase(string token);
37
38 [OperationContract]
39 void Open(string token);
40
41 [OperationContract]
42 System.Data.ConnectionState GetState(string token);
43
44 [OperationContract]
45 void DisposeConnection(string token);
46 #endregion
47
82 [OperationContract]
83 string ExecuteReaderWithBehavior(string token, CommandBehavior behavior);
84
85 [OperationContract]
86 string ExecuteReader(string token);
- CreateConnection takes a string invariantName and returns a string.
- The WCF Service can be used to connect to any data provider installed on the host machine. To know what type to connect to the client must provide the Invariant Name for that provider. This gets passed unmodified to the DbProviderFactories to construct the relevant class factory.
- Returns a token to represent this connection instance.
- Virtually all methods have a token parameter. Because the WCF Service can be used by multiple clients to create multiple connections at a time, the service needs to know which connection to operate against. When the client requests a new object (DbConnection, DbCommand, etc) to be created the service will store it and pass back a unique identifier to the client. All further calls that need to interact with the object must be passed back to the service.
- The token is a GUID so it should be virtually impossible for any other client application to accidentally request access to a data object it didn’t instantiate.
- There is a DisposeConnection method. This should be called when the client Disposes one of the WcfDb* objects to properly clean up the connection on the host.
- Properties are separated in to separate Get & Set methods. This is due to the fact that the first incarnation of this was as an Asp.Net web service. From what I understand you can decorate the separate Get & Set sections of a Property with the [OperationContract] attribute in WCF. However, I chose not to rewrite these sections at this time.
- Overloaded methods aren’t allowed in web services. In the original web service version of this provider, I got around this problem by creating multiple methods with different names for the overloads. (ExecuteReader & ExecuteReaderWithBehavior)
IDataReader
The data reader is one area where I deviated from the model of mapping the contract 1:1 to the data provider interface. An IDataReader object has lots of methods like GetName, GetDecimal, GetDouble, etc. which retrieve metadata or the actual value for a single field at a time. These methods are likely to be called more frequently than any other methods in this contract.
For performance purposes I chose not to have this handled by the service. Instead I added the following method to the service.
129 [OperationContract]
130 DataTable GetCurrentReaderRecord(string token);
After reading a record on the WcfDataReader will retrieve the record with this method. The returned DataTable includes all the data (along with metadata) for the current record. All calls on the WcfDataReader which needs individual field information will retrieve the values from this DataTable.
Previous: Architecture
Next: Service
.NET,
WCF in
WCF Data Provider
Reader Comments