WF and WCF Integration

Source: Internet
Author: User
Tags mysql host hosting

With the advent of Windows Workflow Foundation (WF), Microsoft has gradually introduced various workflow functions to the. NET developer platform. These functions enable developers to build workflows that meet various application needs, from simple ordered workflows to complex state machine workflows that require complex human interaction.

At the same time, business capabilities are increasingly presented through encapsulated service endpoints, so that business functions and business processes can be reused and combined to improve the service-oriented architecture. Windows Communication Foundation (WCF) provides a unified developer API, robust hosting runtime, and flexible configuration-driven solutions to help with deployment, this helps developers easily develop interconnected systems through various features.

Expenditure report example

TheCodeThe example is an example of an "expense report" workflow that establishes a model based on the standard business process for submitting and approving employee reimbursement applications. We have updated the original example to illustrate how to use WCF and. Net 3.0 framework to more effectively host this business process.

In the first "expense report" example released, the. NET remote call is used to provide client applications.ProgramCommunication with the Host application that contains the workflow runtime instance.

The example of the expenditure report that we reconstructed uses WCF to implement communication between the client and the server. In addition, the solution implements a logical structure to separate various problems.

Figure 1. Structure of the solution after reconstruction

It is important to understand how messages are used in the context of a business process. Only in this way can you integrate them into the design. There are several interaction points in the "expense report" lifecycle. Let's take a simple analysis:

    • This process involves three parties: the client, administrator, and expense report host system.

    • This process starts when the client submits a new reimbursement application.

    • We use a rule policy to determine whether a reimbursement application can be automatically approved.

    • If your application for reimbursement cannot be automatically approved, you need to approve the report. Management Personnel must either manually check for new reports to be approved, or be notified of new reports to be approved.

    • If the management personnel does not approve the application within the flexible delay period, the process will automatically reject the application.

    • After the reimbursement application is reviewed, the client and management personnel must be notified of the results in a timely manner.

With WF, we can use the standard activities provided by the Framework to model this process. We can use delayactivity to manage events triggered after a period of time. We can use the rule engine and policyactivity to manage a set of flexible rules and obtain results by asking these rules.

As this is a personnel-oriented process, we must interact with the end user and return the interaction to the workflow. WF provides "local service", handleexternaleventactivity, and callexternalmethodactivity, which provides a comprehensive programming model for communication between the host and workflow.

As this is an important concept for building an interactive workflow, let's take a look at how it is designed into WF.

In order to establish a user interaction model in WF, we must design the conventions used to provide many events and methods. Both the workflow and the host process should understand this agreement. The constructed Convention/interface must be marked with the [externaldataexchange ()] attribute, which identifies it for workflow data exchange. In the example we listed, the workflow uses the iexpenselocalservice interface.

Then we subscribe to a class (called Local Service) that implements this interface when running the workflow ). Workflow activities can be registered to events or methods defined on the interface type, and bound to a locally registered service. This adopts a pattern called "control inversion", which eliminates the tight coupling between workflows and local services of specific types. In the examples we listed, the expenselocalservice class implements the iexpenselocalservice convention.

When the workflow runs for the first time, it can obtain an initial data packet for performing operations. When a workflow arrives at a point that requires external interaction, an event can be bound to handleexternaleventactivity in the workflow. This activity uses the interface type and event as the parameter. When the event is triggered, the workflow is awakened to continue the operation.

If the workflow must callback the local service, you can use callexternalmethodactivity and use the interface and method name as a parameter.

Through these activities, two-way communication can be implemented between the host process and the running workflow. By using the "control reversal" Mode in WF, the tight coupling between the workflow and the local service is avoided.

However, once a cross-host process exists, we must allow interaction to be driven by other systems or even humans. To achieve this level of interaction, we can allocate interactive operations through services, which are then called by other services or user-driven applications. However, WCF is a framework that can flexibly build this messaging function.

In this solution Integrated with WCF, the main advantages are:

    • The service implementation can be separated from the message passing Pipeline Code.

    • This greatly reduces the amount of code and complexity related to system connections.

    • Added Deployment flexibility.

    • You can use direct callback from the host to the client to make information update faster and with lower overhead.

Integrated Work Checklist

To achieve the integration of WF and WCF, there must be a service interface that will provide users with many interface points. Users can start running workflows or interact with them at these interface points. A service model should be built around the interface points between the business process and external entities (such as the persons involved in the process.

Figure 2. Interaction points in the expense report plan

To do this, we must:

    • Define service conventions.

    • Creates a new workflow (or interacts with an existing workflow) through an event.

    • Host the workflow runtime instance to the service host.

In addition to simply hosting workflows, we can also use the WCF duplex channel to return events from the workflow to the client as the user. This is very beneficial in terms of the "expenditure report" because the solution relies on clients to perform service round-robin to implement regular data updates. However, these clients can also receive notifications directly from the service department.

To do this, we must:

    • Define a callback convention.

    • Bind a duplex channel.

Define Service Conventions

Windows Communication Foundation (WCF) requires a formal convention to abstract and define service functions and data exchange. This Convention is defined by declaring an interface in the form of code.

When designing business services, the "Request/response" collaboration mode is usually used. When using this mode, three factors must be taken into account in the provided conventions:

    • The published operation. These operations are functions that the Service publishes to its users and interfaces.

    • Encapsulate messages of structured data for each request and response. These messages are parameters and return types of each method. In terms of WCF, they are generally message conventions, while in simpler cases, they are data conventions.

    • Data Definitions of core business entities that can be exchanged through services. These definitions constitute part of a message. In WCF terms, they are data conventions.

Service Conventions are defined by attribute-based tags. They first define the conventions for providing operations, and then define the specific operations for publishing through the network.

Each Service Convention is clearly marked with the [servicecontract] attribute. This attribute can be declared using the following parameters:

    • Name. Control the convention name declared in the WSDL <porttype> element

    • Namespace. Control the convention name declared in the WSDL <porttype> element

    • Sessionmode. Specifies whether to support session binding.

    • Callbackcontract. Specify the conventions used for client callback

    • Protectionlevel. Specifies whether the protectionlevel attribute must be supported. This attribute is used to declare encryption and digital signature requirements.

Declare operation

After the conventions are defined, the Service is composed of many publish operations. The operation is explicitly added to the Convention through the [operationcontract] attribute mark. Like servicecontract, operationcontract also has many parameters used to control the binding method with the endpoint. These parameters include:

    • Action. Controls the name that uniquely identifies this operation. When an endpoint receives a message, the scheduler uses the control and action to determine the method to be called.

    • Isoneway. Indicates that the operation will accept a "request" message, but will not produce any response. This is different from simply returning a void return type that will generate a "result" message.

    • Protectionlevel. Specifies the encryption and signature requirements for this operation.

The following is an example of a code-based service agreement.

 
[Servicecontract] public interface iexpenseservice {[operationcontract] getexpensereportsresponse getexpensereports (); [operationcontract] getexpensereportresponse getexpensereport (optional );}
Declare message and data entity

When building a message model, you may want to define the load or body for each sent message in the form of a class. This is similar to using tools such as ws contract first (wscf) to build a message model when building Web Services in ASP. NET.

By default, WCF uses a serialization engine called datacontractserializer to implement data serialization and deserialization (that is, back-and-forth conversion with XML ). We add a reference to the system. runtime. serialization namespace to use datacontractserializer, then Mark the class with the [datacontract] attribute, and mark the Members to be released with the [datamember.

[Datacontract] public class getexpensereportsresponse {private list <expensereport> reports; [datamember] public list <expensereport> reports {get {return reports;} set {reports = value ;}}}

The data entity used in the message represents the entity in your business domain. Just like message conventions, we can use datacontractserializer and tag attributes to explicitly add the assigned members. Or, if we only want to build a data model, we can use the public field method, and mark the class as a serialized class.

In this example, we use a data convention to mark message transmission. In practice, you often need to use attributes and SOAP Headers in a more complex architecture. WCF supports defining classes marked with [messagecontract] attributes (which can describe the entire soap encapsulation, not just the body), thus solving these acute problems.

For more information about data conventions and message conventions, see the end of this article.More informationCorresponding msdn library listed in SectionArticle.

Managed workflow Runtime

The Service generally supports creating a new service type instance and maintaining the parallel behavior of the service type instance throughout the session lifecycle. To use a workflow in this case, you must create an instance when the workflow is running and maintain it within the lifecycle of the service host instance (instead of based on each call.

We recommend that you use an extension class that will be activated after the service host is created. This extension class creates and maintains global instances when the workflow is running, so that each individual service instance can access it.

To implement extension on servicehost, you should create a class that implements iextension <servicehostbase>. In this solution, you can find this example in the wfwcfextension class under the wcfextensions Code project.

We need to implement two methods: attach (this method is called when the extension is attached to its parent object) and detach (this method is called when the parent object is detached ).

The attach method shown below will create a new workflowruntime instance and instantiate it for the required service. We store this in a local private field named workflowruntime.

 
Void iextension <servicehostbase>. attach (servicehostbase owner) {workflowruntime = new workflowruntime (workflowservicesconfig); externaldataexchangeservice exsvc = new externaldataexchangeservice (); workflowruntime. addservice (exsvc); workflowruntime. startruntime ();}

As you can see, the initialization during Workflow running also involves adding the service instance to the workflow before it starts running. When building a solution, we recommend that you add all services before starting the running. However, if coupling is an important factor, you will find it more wise to use the later binding method.

In this example, as part of the setupworkflowenvironment method in the expenseservice class, we add the expenselocalservice instance to externaldataexchangeservice after workflowruntime is started.

The following detach method calls stopruntime to close the runtime.

Void iextension <servicehostbase>. Detach (servicehostbase owner) {workflowruntime. stopruntime ();}

Since workflowruntime is created and initialized during the startup of the service host, any existing workflow can continue to work before the service call is executed. When the service host is terminated, the workflow is completely closed during running.

Note that we recommend that you use the workflow persistence service (such as sqlworkflowpersistenceservice) when hosting workflows and building long-term workflow models. This is a basic principle. This will provide a mechanism for implementing State persistence, and will not be affected even if the application or process is restarted.

Create a service

To create a class that contains service behaviors, you must implement one or more interfaces used to define service conventions.

 
Public class expenseservice: iexpenseservice, iexpenseserviceclient, iexpenseservicemanager

To integrate with workflows, our service methods do not contain business logic, but contain code to control events or hand over events to running workflows that encapsulate business processes.

To process a workflow, we can start a new workflow or interact with an existing running workflow.

To create a new workflow instance, you need to use workflowruntime to instantiate a new instance of the required workflow type. We have created such an instance in the servicehost extension class. To obtain the reference to this instance, we must use operationcontext to find the custom extension.

Wfwcfextension extension = operationcontext. Current. Host. Extensions. Find <wfwcfextension> (); workflowruntime = extension. workflowruntime;

Operationcontext is a class for us to access the service method to extend the context. As you can see in the previous code, it provides a singleton named current to show us the context of the current service method. We call the host attribute to return the instance to the servicehost to which it belongs, and then find the extension based on its type.

After obtaining the reference of the extended instance, you can return workflowruntime through the public attribute and use it to create a new instance of sequentialworkflow.

 
Guid workflowinstanceid = submitexpensereportrequest. report. expensereportid; Assembly ASM = assembly. load ("expenseworkflows"); Type workflowtype = ASM. getType ("expenseworkflows. sequentialworkflow "); workflowinstance = workflowruntime. createworkflow (workflowtype, null, workflowinstanceid); workflowinstance. start (); expenselocalservice. raiseexpensereportsubmittedevent (workflowinstanceid, submitexpensereportrequest. report );

In the code above, we created a new workflow instance based on the predefined type. Although this can also be achieved through direct type instantiation, the above method tells us that you can flexibly create a workflow at runtime Based on Dynamic Rules (rather than through strongly typed binding.

The last line of code triggers the event processed by the first handleexternaleventactivity in the workflow, marking the start of the workflow. This event is triggered through an expenselocalservice instance. In this example, expenselocalservice starts a new workflow or submits an event to an existing workflow to interact with the workflow. We use this class as a mechanism to encapsulate business processes. Internally, we use WF to implement this mechanism.

Figure 3. The workflow starts with handleexternaleventactivity.

Another scenario we will deal with is how to call back to an existing workflow and trigger events. We must hand over the event to the workflow engine that prompts the existing workflow to receive the event and continue to process it.

An example of an event triggered in the expense report process occurs when the administrator needs to approve the event. The workflow will call an external Method for requestmanagerapproval to send an alert to the management that they must approve or reject the new expense report.

A workflow contains a listenactivity that is always in the blocking state before a possible event occurs. In this example, we receive an event indicating that the Administrator has reviewed the report or that the time limit for delayactivity has been exceeded.

Figure 4. managerapproval custom activity process
 
Guid workflowinstanceid = submitreviewedexpensereportrequest. Report. expensereportid; worker E = new worker (workflowinstanceid, report, review); If (expensereportreviewed! = NULL) {expensereportreviewed (null, e );}

When a manager uses the managerapplication to review the report, a service callback is performed on the host to call the submitreviewedexpensereport method that triggers the expensereportreviewed event.

When an event is thrown to handleexternaleventactivity in a workflow, you must know the guid of the workflow instance to route the event.

Each event is triggered by eventargs, which enables us to pass data back to the workflow through the event model. In this example, we can transmit detailed information about the current report status and audit activity context.

In a workflow, events are automatically bound to the workflow through the attributes of handleexternaleventactivity.

Figure 5. Bind handleexternaleventactivity to the iexpenselocalservice interface.

First, specify the interface type that must be marked with the [externaldataexchange] attribute, and then specify the event that handleexternaleventactivity will subscribe to on this interface.

The event parameter must be derived from the externaldataeventargs class. This means that each event contains the context (for example, the instanceid of the workflow ). Then, the workflow is responsible for routing events to the correct workflow instance during running so that the workflow can continue. If the persistent service is used, the hydration and rehydration of all running states of the workflow are also managed throughout the execution period.

Managed Service

To host the WCF Service, it must run in the servicehost container.

To learn how to use WCF for hosting, let's first take a look at several available alternatives:

    • For standard Windows processes, You can manually create and open the servicehost instance.

    • When you host a web endpoint (Web Service) through Microsoft Internet Information Services (IIS) 6.0, use the custom httphandler provided in the system. servicemodel namespace.

    • When hosting IIS 7, you can use Windows activation Service (was) to host endpoints.

When building a web service, you usually choose to use Internet Information Services for hosting. When building a single instance port that will be used as the background program, you usually choose to host it through the windows service.

In this example, we host a major service instance in a Windows console application. The hosting method is similar to that of a Windows service.

To deploy services, we must create an instance of the servicehost class and open its endpoints for each service type to be released. Servicehost uses many parameters as part of its constructor. However, the main parameters are type parameters or instances of classes that implement servicecontract.

    • If you want to use percall or persession instantiation, use type.

    • If single instantiation is used, use a single instance.

 

After the host is created, it analyzes all available configurations (detailed descriptions are provided in the following configuration Deployment Section) and merges them with any explicitly added configurations, to determine available endpoints and open those endpoints for publishing. After receiving a call from the client, the host processes the request in the new background working thread and follows the name and action instructions specified by the soap in the message, route it to the corresponding service operation.

Using (servicehost = new servicehost (New expenseservice () {wfwcfextension = new wfwcfextension ("workflowruntimeconfig"); servicehost. extensions. add (wfwcfextension); servicehost. open (); // stop the process here, such as console. readline (); servicehost. close ();}

When configuring servicehost, you must first open the endpoint for the connection. Therefore, you can interact with the Host object before calling. open (), as shown in the previous code. We recommend that you use the scope to dispose of servicehost before use. We recommend that you call close () when the scope ends to completely close all active connections and endpoints.

Configure and deploy

WCF provides a mechanism that allows you to configure endpoints through xml configuration to separate deployment issues from implementation. This allows the Administrator to modify the service policy without re-deploying the code.

Each service is published on one or more endpoints. An endpoint is an addressable connection point, and the client can use the service for it. In WCF, each endpoint is declared with three attributes, which are the well-known ABC of WCF.

They are "address" (a), "binding" (B), and "Convention" (c ).

Address: The unique addressable position of this endpoint. In general, the address is the URI that provides an absolute address for you. The service listens for requests at this address, for example, http: // myhost/myservice or net. TCP: // MySQL HOST: 400/myservice

Bind: A policy that defines the communication protocol between a service and its users. Binding specifies several elements, such as the transmission type used, message encoding mode, and data serialization mode. WCF comes with many ready-to-use bindings that support the most common cases.

Conventions: The operations and data to be released are defined in the form of code through the interface.

To configure the service, we must declare the configuration of the declared service and configure any number of endpoints for the service. As the service may be implementing any number of conventions, this will also affect the number of endpoints to be released.

The following is a configuration example.

 
<Services> <service name = "expenseservices. expenseservice "> <endpointaddress =" http: // localhost: 8081/expenseservice/manager "binding =" wshttpbinding "Contract =" expensecontracts. iexpenseservicemanager "/> <endpointaddress =" http: // localhost: 8081/expenseservice/client "binding =" wsdualhttpbinding "Contract =" expensecontracts. iexpenseserviceclient "/> </service> </services>

In this configuration example, we configure the service declaration of the expenseservices. expenseservice type. In this way, we can find this configuration when we create a new servicehost based on this type of instance.

Use Services

Through the channelfactory class, you can use WCF to use the service. Channelfactory provides the service agreement proxy instance for us to connect to the specified endpoint in the configuration through the factory mode. We can use the runtime information (such as security creden and certificates used for message encryption) to configure the factory, or dynamically determine the endpoint information.

Private jsoncontainer () {channelfactory <iexpenseservicemanager> factory = newchannelfactory <iexpenseservicemanager> ("expenseservicemanager"); iexpenseservicemanager proxy = factory. createchannel (); Return proxy ;}

As you can see, we first create a factory instance that uses generic parameters for service conventions to construct a more precise factory that will only return the required instance. We also specify parameters used to determine the configuration of the endpoint. In this example, we use the endpoint configuration named expenseservicemanager, which is the configuration in our application configuration file.

 
<System. servicemodel> <client> <endpoint name = "expenseservicemanager" address = "http: // localhost: 8081/expenseservice/manager" binding = "wshttpbinding" Contract = "expensecontracts. iexpenseservicemanager "/> </client> </system. servicemodel>

You will find that the endpoint definition is exactly consistent with the definition declared in the host configuration. Generally, configuration differences occur only when the IP addresses of the client and server are different due to network configuration, or when the custom line is implemented.

If the Windows SDK is installed, you will find a tool for automatically creating proxy classes and Endpoint configurations. You can integrate it into your solution. This tool can be used only when the target Service publishes a description of its metadata through WSDL or WS-metadataexchange.

Configure duplex channel

Till now, we have been assuming that our communication stream adopts the request/response collaboration mode, and the message is sent by the user and responded by the Service. WCF supports many alternative message streams, such as one-way ("instant release" mode) or two-way duplex communication. If you can process a message stream in which each party can start a session, you need to use a duplex or bidirectional channel. Duplex channels are very effective for systems that are more closely connected and support data transmission in any direction. For example, to provide a callback that begins with the event processing process, the duplex channel is very useful.

Implement client callback

In WCF, client callback is implemented through a concept called callbackcontracts. For published conventions, we can specify another convention to define the code callback operations that the client will publish and can run on the service.

To declare callbackcontract, the interface type should be specified in the service agreement for callback issuance.

 
[Servicecontract (callbackcontract = typeof (iexpenseserviceclientcallback)]

You also need to bind a duplex channel, such as nettcpbinding or wsdualhttpbinding. TCP-based duplex communication is implemented by establishing and maintaining bidirectional connections throughout the message exchange process. HTTP-based duplex communication is implemented through callback of the client listener. Because the client may not know the return path, or you may want to customize it through configuration, we can use custom binding configuration to declare an alternative clientbaseaddress.

<Endpoint binding = "wsdualhttpbinding" bindingconfiguration = "alternativeclientcallback"/> <bindings> <dependency> <binding name = "alternativeclientcallback" clientbaseaddress = "http: // localhost: 8082/expenseservice/clientcallback "/> </wsdualhttpbinding> </bindings>
Implement callback on the client

The method for implementing callback conventions is exactly the same as that for implementing service conventions. We must provide the Implementation of the defined interface.

 
Class callbackhandler: iexpenseserviceclientcallback {public void expensereportreviewed (expensereportreviewedrequest) {// implement the client logic here to respond to the callback .}}

In order for the host to call back to the callbackhandler class instance, the established client channel must be aware of the duplex characteristics of the connection.

As described earlier, bind a channel that supports duplex is used first. Second, when initializing the connection to the service endpoint, use the channelfactory subclass version named duplexchannelfactory to create a duplex connection with the service.

Private jsoncontext () {instancecontext context = new instancecontext (New callbackhandler (); duplexchannelfactory <iexpenseserviceclient> factory = new duplexchannelfactory <inline> (context, "expenseserviceclient "); iexpenseserviceclient proxy = factory. createchannel (); Return proxy ;}

The main difference between using duplexchannelfactory is that you must first initialize the callbackhandler class instance and pass it to the factory constructor to initialize the context used by the callback.

Implement host callback

From the perspective of the host, we can obtain a reference to the client-oriented callback through the callback channel defined in the iexpenseserviceclient convention.

 
[Servicecontract (callbackcontract = typeof (iexpenseserviceclientcallback)] public interface iexpenseserviceclient: iexpenseservice

Callbackcontract attribute declaration is used to define the interface of the host callback convention.

For callback, we call operationcontext. Current. getcallbackchannel to obtain the reference of the callback convention, as shown below.

Iexpenseserviceclientcallback callback = operationcontext. Current. getcallbackchannel <iexpenseserviceclientcallback> (); callback. expensereportreviewed (newexpensereportreviewedrequest (E. Report ));

After obtaining a reference to the callback channel, we can call it normally.

Conclusion

Windows Workflow Foundation provides a general framework for defining workflows and a robust Runtime Engine for hosting and interacting with running workflows.

The Windows Communication Foundation provides a general framework for building Interconnected Systems, and provides developers with consistent APIs and a rich set of functions to define communication methods.

You can combine these two frameworks to provide a flexible and comprehensive application platform for building and deploying distributed business processes in your environment. WF allows you to model and encapsulate business logic and processes, while WCF provides you with a message transmission infrastructure with multiple system distribution options.

The following principles must be kept in mind when designing a service:

    • Persistent services should be used to support long-running workflows.

    • Service operations can be performed by running workflows and triggering events. The workflow should be designed to trigger events when necessary, and respond to events when interacting with external (such as external services or personnel.

    • The workflow asynchronously executes the service call. Therefore, you can design the data returned from the service and the status of the data at that time. To use the synchronization method, you can use the manualworkflowschedulerservice class to manually schedule the workflow execution.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.