Can we host the workflow service as a windows service?

I am working on a registration application that requires that I have a Workflow that is open as a Workflow Service. We want to host it as a Windows service (we don’t want to host a workflow service as an .svc file in IIS). Another reason to have it as a Windows service is to be able to communicate with the service through named pipes.

Can we provide the Workflow service through named pipes without hosting it in IIS?

+4
source share
2 answers

Yep bep, you certainly can. At least I have done so much with Candidate Release Workflow 4.

Consider

// a generic self-hosted workflow service hosting thingy. Actual // implementation should contain more logging and thread safety, this // is an abbreviated version ;) public class WorkflowHost { // NOTE: with Workflow, it helps to maintain a concept of // Workflow definition [the Activity or WorkflowService from // a designer] and a Workflow instance [what is running within // WorkflowInvoker, WorkflowApplication, WorkflowServiceHost]. // a definition may be used to generate an instance. an instance // contains run-time state and cannot be recycled into a new // instance. therefore, to repeatedly re-host a WorkflowService // we need to maintain references to original definitions and // actual instances. ergo services and hosts maps // // if you are special purpose and require support for one and // only one service and endpoint\uri, then you may reduce this // to a simple tuple of Uri, WorkflowService, WorkflowServiceHost // services represents a definition of hosted services private readonly Dictionary<Uri, WorkflowService> _services = new Dictionary<Uri, WorkflowService> (); // hosts represents actual running instances of services private readonly Dictionary<Uri, WorkflowServiceHost> _hosts = new Dictionary<Uri, WorkflowServiceHost> (); // constructor accepts a map of Uris (ie service endpoints) to // workflow service definitions public WorkflowHost (IDictionary<Uri, WorkflowService> services) { foreach (KeyValuePair<Uri, WorkflowService> servicePair in services) { _services.Add (servicePair.Key, servicePair.Value); } } // have your windows service invoke this to start hosting public void Start () { if (_hosts.Count > 0) { Stop (); } foreach (KeyValuePair<Uri, WorkflowService> servicePair in _services) { WorkflowService service = servicePair.Value; Uri uri = servicePair.Key; WorkflowServiceHost host = new WorkflowServiceHost (service, uri); host.Open (); _hosts.Add (uri, host); } } // have your windows service invoke this to stop hosting public void Stop () { if (_hosts.Count > 0) { foreach (KeyValuePair<Uri, WorkflowService> servicePair in _services) { WorkflowService service = servicePair.Value; Uri uri = servicePair.Key; IDisposable host = _hosts[uri]; host.Dispose (); } _hosts.Clear (); } } } 

I believe that endpoint configuration can be set through the standard Wcf service configuration sections in App.config. In my experiments with Workflow, I personally did not try to change the default transport level.

The above shared hosting hosting class [i.e. he is the host of WorkflowServices]. This allows us to reuse this hosting feature in the console, WinForm, WPF or yes, even in a WindowsService application. The following is a WindowsService that uses our host class

 // windows service. personally i would abstract service behind // an interface and inject it, but again, for brevity ;) public partial class WorkflowWindowsService : ServiceBase { WorkflowHost _host; public WorkflowWindowsService () { InitializeComponent(); Dictionary<Uri, WorkflowService> services = new Dictionary<Uri, WorkflowService> (); // do your service loading ... // create host _host = new WorkflowHost (services); } protected override void OnStart(string[] args) { _host.Start (); } protected override void OnStop() { _host.Stop (); } } 

If you replayed WorkflowServices in VS2010RC, then you already know that WorkflowServices are not Xaml classes like their Workflow cousins. Instead, they are saved as free Xaml files with the extension .xamlx. For WorkflowServices [as far as I know] there is no Intellisense support for development and time, and they are not recognized as declared types, so our only options for loading WorkflowService at runtime are

  • Read the clean Xaml markup directly from the .xamlx file.
  • Read pure Xaml markup from another source [inline string, resource or other source]

In any case, we must interpret the markup and create a WorkflowService definition. The following converts the string [, which may be a file name or markup] to a WorkflowService. Keeners may also point out that there is a difference between this process and the process of converting Workflow markup to Workflow definitions.

 // converts a string value [either pure xaml or filename] to a // WorkflowService definition public WorkflowService ToWorkflowService (string value) { WorkflowService service = null; // 1. assume value is Xaml string xaml = value; // 2. if value is file path, if (File.Exists (value)) { // 2a. read contents to xaml xaml = File.ReadAllText (value); } // 3. build service using (StringReader xamlReader = new StringReader (xaml)) { object untypedService = null; // NOTE: XamlServices, NOT ActivityXamlServices untypedService = XamlServices.Load (xamlReader); if (untypedService is WorkflowService) { service = (WorkflowService)(untypedService); } else { throw new ArgumentException ( string.Format ( "Unexpected error reading WorkflowService from " + "value [{0}] and Xaml [{1}]. Xaml does not define a " + "WorkflowService, but an instance of [{2}].", value, xaml, untypedService.GetType ())); } } return service; } 
+5
source

Yes it is possible. You will need to create your own service. See Hosting and Using WCF Services on MSDN, especially Hosting on Windows Services.

+1
source

Source: https://habr.com/ru/post/1305600/


All Articles