Writing Your First Offline Application
It's time to write some code. The sample application consists of three Web service methods that use the request/response message pattern and connect to SQL Server 2000's Northwind database. The three services are:
- GetCustomers: Retrieves all customers from the Customers table. This reference data is needed for making new orders.
- GetProducts: Retrieves all products from the Products table. This is also needed for making new orders.
- PlaceOrder: Transfers a new order to the back end system for processing. It creates new records in the Orders and Order Details tables. I used the PlaceOrder and PlaceOrderDetails stored procedures.
For each Web service method I've created the necessary request and response messages. For the method GetCustomers
there are the GetCustomersRequest
messages. The ProcessMessage
function handles the messages and returns the required response.
public GetCustomersResponse GetCustomers(
public GetProductsResponse GetProducts(
public PlaceOrderResponse PlaceOrder(
function contains all the code needed to process a request message. It provides the following operations:
- Go online: switches to the online mode
- Go offline: switches to the offline mode
- Place Order: creates a new service request
- Download Reference Data: forces the download of the reference data (customers, products)
- Add: adds a new order detail to the current order
Here's a more detailed look at the client code. At startup, the application creates a new Controller object inside the Main
function. The Controller accepts the current view as a parameter.
public static void Main()
frmMain view = new frmMain();
mainController = new Controller(view);
catch (Exception ex)
mainController = null;
if (mainController != null)
The Controller object encapsulates the logic from the view in the presentation layer. Therefore the current view is stored in the private variable named view
. There are three other notable private variables:
- offlineBlockBuilderInstance: stores the singleton instance of the offline building blocks from which the complete functionality of the building block can be accessed
- currentState: stores the current state of the smart client (offline, online)
- northwindServiceAgent: stores the service agent that communicates with the back end Web services
The Controller object's constructor initializes all variables and defines callback functions for the following events:
- ConnectionStateChangedEvent: This event is exposed from the building block and is raised when the underlying connection state is changed from online to offline or vice versa.
- CustomerReferenceDataAvailableEvent: The Northwind service agent raises this event when the customer reference data is available to the smart client.
- ProductsReferenceDataAvailableEvent: The Northwind service agent raises this event when the products reference data is available to the smart client.
To switch the Smart Client Offline Application Block into the offline or online mode you have only to call the appropriate methods of the class ConnectionManager, which raises the ConnectionStateChangedEvent.
public void GoOline()
public void GoOffline()
private void ConnectionStateChangedEvent(
object sender, ConnectionStateChangedEventArgs e)
currentState = e.CurrentState;
if (currentState == ConnectionState.OffLine)
ensures the proper UI is delivered, depending on whether the current mode is online of offline. Next, the Controller object must call the function DownloadReferenceData
to begin download of customer and product reference data. The Northwind service agent is responsible for this action.
public void DownloadReferenceData()
Both functions in the Northwind service agent receive request messages.
public class NorthwindServiceAgent : ServiceAgent
public void GetCustomersReferenceDat(
string onlineProxyAssemblyName = "SmartClient";
string onlineProxyClassName =
string onlineProxyMethodName = "GetCustomers";
string specificServiceAgentMethodToBeInvoked =
int absoluteExpirationTime = 600;
string cacheKey = "SmartClient_Customer";
OnlineProxyContext onlineProxyMethodContext =
ServiceAgentContext specificServiceAgentContext =
ReferenceDataDefinition refDataDefinition =
Every service agent must derive from the base class ServiceAgent. This ensures that every service agent in the system is registered with the service agent registry under a GUID.
|Figure 8. Service Request Message: This figure shows how a service request message is queued locally and executed through the executor.|
To call a specific method on the online proxy you must create a new instance of the OnlineProxyContext class. This instance contains the assembly name, the class name, and the method name to be invoked, as these data are needed to call the method through Reflection. Furthermore you have to create a new instance of the class ServiceAgentContext. This instance contains all information needed to call a callback function on the service agent when the service request completed successfully.
At the end you have to create a new instance of the class ReferenceDataDefinition. This instance contains all data needed to store the requested reference data locally in the configured cache store. The last method called is LoadData
of the class DataLoaderManager. When the smart client is online the service request is taken directly from the queue and executed against the specified online proxy. But when the smart client is in the offline mode, the service request is stored in the configured queue storage provider until a connection is made (see Figure 8