The WF runtime is embodied by the WorkflowRuntime class, which not surprisingly is the central type in the System.Workflow.Runtime namespace. The methods, properties, and events of the WorkflowRuntime class fall into two general categories. The members shown in Listing 5.1 allow you to instantiate the WF runtime and manage it and the services it contains. We will discuss this functionality first. The remaining members of WorkflowRuntime, which we'll look at later in the chapter, allow you to create and manage instances of WF programs. Listing 5.1. WorkflowRuntime
In order to run a WF program, you must first instantiate the WF runtime. The process of instantiating, configuring, and starting the WF runtime is called hosting. The WF runtime is represented in an application by a CLR object of type WorkflowRuntime, and as such can be hosted in any CLR application domain. As depicted in Figure 5.1, WF imposes no restriction on the number of WorkflowRuntime objects that can exist in any given application domain (though it is atypical to need more than one WF runtime in a given application domain). Figure 5.1. WF runtime hosted in CLR application domains![]() The simplest boilerplate code for hosting the WF runtime looks like this: using (WorkflowRuntime runtime = new WorkflowRuntime()) { runtime.StartRuntime(); ... runtime.StopRuntime(); } ServicesThe WF runtime is a container of services. These services are actually just any CLR objects of your choosing; there are no special requirements that must be met in order to become a service (in the context of the WF runtime). As we have seen in examples of previous chapters (see the WriterService in Chapter 3, "Activity Execution"), you can develop custom services on which your activities depend and then add these services to the WF runtime. Activities obtain the services they need using the GetService method of ActivityExecutionContext. WorkflowRuntime defines several simple methods (AddService, GetService, RemoveService) for managing its set of contained services. The code to programmatically add a service to the WF runtime, thereby making it available to activities in WF program instances, is simple: using (WorkflowRuntime runtime = new WorkflowRuntime()) { WriterService writer = new WriterService(); runtime.AddService(writer); ... runtime.StartRuntime(); ... } Services can also be added to the WF runtime via a configuration file. In some deployment scenarios it is more desirable to provide a configuration file for the application hosting the WF runtime than to perform programmatic addition of services. The WF programming model gives you both options. Please refer to the WF SDK for sample usage of configuration files. WF Runtime ServicesIn addition to passively providing services to activities, the WF runtime relies upon a set of well-known services as it manages WF program instances. The core WF runtime is as lightweight as possible so that several aspects of its functionality can be customized by a host application. These well-known services, sometimes referred to as WF runtime services, are defined as types within the System.Workflow.Runtime.Hosting namespace. Following are the three WF runtime services that we will discuss here:
By abstracting these capabilities into standalone services, the core WF runtime remains lightweight and as a consequence can be utilized differently in different hosting applications. WF provides one or more useful implementations of each of these services, but as needed you can develop custom implementations that suit the needs of your specific solution. The three services listed previously are defined as abstract classes, which allow multiple concrete implementations to be written and interchanged without affecting the WF runtime. Table 5.1 lists the WF-provided implementations of each WF runtime service. If no implementation of one of these services is added to the WF runtime (either programmatically or via a configuration file), the default implementation of that service is automatically added during the execution of the StartRuntime method of WorkflowRuntime. This ensures a valid WF runtime at the return of the StartRuntime method. All of the types mentioned in Table 5.1 are defined in the System.Workflow.Runtime.Hosting namespace.
To summarize the information in Table 5.1, the WF runtime requires exactly one WorkflowLoaderService, and exactly one WorkflowSchedulerService. The WF runtime requires either zero or one service of type WorkflowPersistenceService, which means that it is possible to run WF programs without the possibility of passivation. When you configure the WF runtime, you are free to mix and match the WF-provided service implementations with custom implementations of the abstract classes (within the constraints just mentioned) and, as we have already discussed, you are free to add whatever additional services are needed by your activities. Unlike other services, the WF runtime services are used exclusively by the WF runtime, and are not available to activities in WF program instances. Calling ActivityExecutionContext.GetService returns null if the type of the requested service is any of the WF runtime service types. |