Welcome to EMC Consulting Blogs Sign in | Join | Help

Merrick Chaffer's Blog

Windows Workflow SqlWorkflowPersistenceService configuration using app.config

I was reading the other day from the microsoft msdn (http://msdn2.microsoft.com/en-us/library/aa349366.aspx) that you can add the SqlWorkflowPersistence service to your WorkflowRuntime instance via the app.config. It says the following…

Adding SqlWorkflowPersistenceService to the Runtime Engine

You can add runtime services to the Windows Workflow Foundation runtime engine programmatically or by using an application configuration file.

To modify app.config for the SqlWorkflowPersistenceService

1.           In the Services element in the app.config file, create a new element named add.

 

However it fails to mention which section you should be adding to the <configSections> of your app.config, which will in turn actually house afore mentioned Services element.

Finally cracked it myself though, and this is how you can add the SqlWorkflowPersistenceService to your workflow runtime instance using a configuration file.

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

       <configSections>

              <section name="WorkflowRuntime" type="System.Workflow.Runtime.Configuration.WorkflowRuntimeSection, System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

       </configSections>

       <WorkflowRuntime Name="MyApplication">

              <Services>

                     <add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

                            ConnectionString="Data Source=myDatabaseServer;Initial Catalog=DatabaseName;Persist Security Info=True;User ID=mySqlUser;Password=myPassword;Workstation ID=WindowsWorkflow"

                            UnloadOnIdle="true"

                            LoadIntervalSeconds="5"

                            OwnershipTimeoutSeconds="5"

                            EnableRetries="false"/>

              </Services>

       </WorkflowRuntime>

</configuration>

Then in code you simply pass in the name of the configuration section when instantiating an instance of the WorkflowRuntime class

private WorkflowRuntime _wfRuntime;

public static void Main(string[] args)

{

if (_wfRuntime == null)

                _wfRuntime = new WorkflowRuntime("WorkflowRuntime");

}

 

The benefits of this are clear for deployment, as you can now modify settings such as the database it uses and the LoadIntervalSeconds without having to rebuild and redeploy your application.

Note, to find the names of the extra configuration parameters such as the ConnectionString, I used .Net reflector to view the constructor overload for the SqlWorkflowPersistence service that takes a namevaluecollection of parameters as it’s argument

public SqlWorkflowPersistenceService(NameValueCollection parameters)
{
    this._serviceInstanceId = Guid.Empty;
this.loadingInterval = new TimeSpan(0, 2, 0);
    this.maxLoadingInterval = new TimeSpan(0x16d, 0, 0, 0, 0);
    this.timerLock = new object();
    this.infinite = new TimeSpan((long) (-1));
    if (parameters == null)
    {
        throw new ArgumentNullException("parameters", ExecutionStringManager.MissingParameters);
    }
    this._ownershipDelta = TimeSpan.MaxValue;
    if (parameters != null)
    {
        foreach (string text in parameters.Keys)
        {
            if (!text.Equals("ConnectionString", StringComparison.OrdinalIgnoreCase))
            {
                if (text.Equals("OwnershipTimeoutSeconds", StringComparison.OrdinalIgnoreCase))
                {
                    int actualValue = Convert.ToInt32(parameters["OwnershipTimeoutSeconds"], CultureInfo.CurrentCulture);
                    if (actualValue < 0)
                    {
                        throw new ArgumentOutOfRangeException("OwnershipTimeoutSeconds", actualValue, ExecutionStringManager.InvalidOwnershipTimeoutValue);
                    }
                    this._ownershipDelta = new TimeSpan(0, 0, actualValue);
                    this._serviceInstanceId = Guid.NewGuid();
                }
                else if (text.Equals("UnloadOnIdle", StringComparison.OrdinalIgnoreCase))
                {
                    this._unloadOnIdle = bool.Parse(parameters[text]);
                }
                else if (text.Equals("LoadIntervalSeconds", StringComparison.OrdinalIgnoreCase))
                {
                    int seconds = int.Parse(parameters[text], CultureInfo.CurrentCulture);
                    if (seconds > 0)
                    {
                        this.loadingInterval = new TimeSpan(0, 0, seconds);
                    }
                    else
                    {
                        this.loadingInterval = TimeSpan.Zero;
                    }
                    if (this.loadingInterval > this.maxLoadingInterval)
                    {
                        throw new ArgumentOutOfRangeException("LoadIntervalSeconds", this.LoadingInterval, ExecutionStringManager.LoadingIntervalTooLarge);
                    }
                }
                else
                {
                    if (!text.Equals("EnableRetries", StringComparison.OrdinalIgnoreCase))
                    {
                        throw new ArgumentException(string.Format(Thread.CurrentThread.CurrentCulture, ExecutionStringManager.UnknownConfigurationParameter, new object[] { text }), "parameters");
                    }
                    this._enableRetries = bool.Parse(parameters[text]);
                    this._ignoreCommonEnableRetries = true;
                }
            }
        }
    }
    this.configParameters = parameters;
}

 

Published 25 April 2007 11:43 by merrick.chaffer

Comments

No Comments
Anonymous comments are disabled

This Blog

Syndication

News

Powered by Community Server (Personal Edition), by Telligent Systems