Archive

Archive for the ‘workflow’ Category

Activity Validation for Bound Properties

September 27, 2007 Leave a comment

One of the readers (Andrew) of my Pro WF book recently had a question about page 114 of the book. This page contains the code for a custom activity validator class that enforces design-time requirements. In this example, I wanted to make sure that two properties of the target activity were set at design-time.

Andrew pointed out that the code only accepts statically set values for the properties. If you set these dependency properties by binding them to another property, the validation fails. He’s right. That particular example code only demonstrates how to validate against statically set values.

To solve the problem, all you need to do is call the IsBindingSet method of the base Activity class. Here is the revised code from page 114 (Listing 3-11) that now works for statically set or bound property values:

using System;
using System.Workflow.ComponentModel.Compiler;

namespace CustomActivityComponents
{
    /// <summary>
    /// Validator for MyCustomActivity
    /// </summary>
    public class MyCustomActivityValidator : ActivityValidator
    {
        public override ValidationErrorCollection Validate(
            ValidationManager manager, object obj)
        {
            ValidationErrorCollection errors = base.Validate(manager, obj);
            //only validate a single custom activity type
            if (obj is MyCustomActivity)
            {
                MyCustomActivity activity = obj as MyCustomActivity;
                //only do validation when the activity is in a workflow
                if (activity.Parent != null)
                {
                    if (activity.MyInt == 0)
                    {
                        if (!activity.IsBindingSet(MyCustomActivity.MyIntProperty))
                        {
                            errors.Add(
                                ValidationError.GetNotSetValidationError(
                                    "MyInt"));
                        }
                    }

                    if (activity.MyString == null ||
                        activity.MyString.Length == 0)
                    {
                        if (!activity.IsBindingSet(MyCustomActivity.MyStringProperty))
                        {
                            errors.Add(new ValidationError(
                                "MyString Property is incorrect", 501));
                        }
                    }
                }
            }
            return errors;
        }
    }
}
Advertisements
Categories: .NET, general, technology, workflow

Visual Studio 2008 (Orcas) Feature: Instantiating Objects in WF Rules

August 28, 2007 Leave a comment

One of the new WF-related features in Visual Studio 2008 (Orcas) is the ability to new-up objects from within a rule. Previously, this seemingly simple task of creating a new object wasn’t possible within a rule. Now it is.

To illustrate this new feature, consider the following contrived example. Assume that you have a workflow that must return an instance of the following class:

using System;

namespace NewUpRules
{
    public class MyClass
    {
        public MyClass(String dayOfWeekDesc)
        {
            _dayOfWeekDesc = dayOfWeekDesc;
        }

        private String _dayOfWeekDesc;
        public String DayOfWeekDesc
        {
            get { return _dayOfWeekDesc; }
            set { _dayOfWeekDesc = value; }
        }
    }
}

Previously, your workflow could use a PolicyActivity and implement a few rules, but you would have to create an instance of this class in code instead of in the rule. However, now you can implement a rule that directly creates an instance of the object like this:

Condition:
System.DateTime.Now.DayOfWeek == System.DayOfWeek.Monday
Then Actions:
this.MyWFResult = new NewUpRules.MyClass("Starting a new work week")
Else Actions:
this.MyWFResult = new NewUpRules.MyClass("Some other day")

The MyWFResult variable is assumed to be a workflow variable that is used to return the resulting instance of MyClass to the host application.

But you’re not limited to creating objects in the rule actions. You can also new-up objects in the Condition portion of the rule. Consider this class:

using System;

namespace NewUpRules
{
    public class MyDayOfWeekChecker
    {
        private DateTime _dateToCheck;
        public MyDayOfWeekChecker(DateTime value)
        {
            _dateToCheck = value;
        }

        public Boolean IsStartOfWorkWeek
        {
            get
            {
                return (_dateToCheck.DayOfWeek == DayOfWeek.Monday);
            }
        }
    }
}

A DateTime value is passed to the constructor of this class, and an IsStartOfWorkWeek property is defined which returns a Boolean. With the VS 2008 enhancements, you can now create an instance of this class and use it in a rule condition like this:

Condition:
new NewUpRules.MyDayOfWeekChecker(System.DateTime.Now).IsStartOfWorkWeek
Then Actions:
this.MyWFResult = new NewUpRules.MyClass("Starting a new work week")
Else Actions:
this.MyWFResult = new NewUpRules.MyClass("Some other day")

Granted, this isn’t the most exciting new feature in Orcas, but I do think it is a welcomed change that improves the rules capabilities in WF. Note: All of this code works in Beta 2 of Orcas.

Another reference

July 25, 2007 Leave a comment

Oops…In my last post, I missed this reference to my Pro WF book:

http://spsfactory.blogspot.com/2007/07/bruces-fantastic-pro-wf-windows.html

Maybe there are others out there that I just haven’t found yet.  If you’ve referenced my book on your blog or site, I’d love to know about it.

Categories: .NET, general, technology, workflow

A quick search

July 21, 2007 Leave a comment
Categories: .NET, general, technology, workflow

Orcas Beta 1

June 23, 2007 Leave a comment

I realize this isn’t exactly the latest ground-break news, but the Orcas beta 1 is now available here.  I’ve downloaded and installed the beta but haven’t had the chance to really get into it yet.  I’m looking forward to trying out some of the new WF features, including the WCF/WF integration.

Categories: workflow

Persistence and Tracking together

May 23, 2007 1 comment

A reader of my workflow book recently wrote me with a question about the standard persistence and tracking services. Their question concerned how to use both of these standard services at the same time. Specifically, they wanted to know how to specify two different database connection strings in the App.config.

There’s really two separate questions there. First, how do you specify two different connection strings for the services, presumably pointing to two different databases. Second, is that how you should use these two services together?

To answer the first question, you can specify the connection string in either the CommonParameters section of the App.Config, or inline as an attribute of the service itself.

For example, here is an App.Config that provides two different database connection strings, one for each service:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="WorkflowRuntime"
    type="System.Workflow.Runtime.Configuration.WorkflowRuntimeSection,
          System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,
          PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <WorkflowRuntime>
    <Services>
      <add type="System.Workflow.Runtime.Tracking.SqlTrackingService,
          System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,
          PublicKeyToken=31bf3856ad364e35"
      ConnectionString="Initial Catalog=WorkflowTracking;
          Data Source=localhostSQLEXPRESS;
          Integrated Security=SSPI;" />
      <add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService,
          System.Workflow.Runtime, Version=3.0.00000.0,
          Culture=neutral, PublicKeyToken=31bf3856ad364e35"
      UnloadOnIdle="true" LoadIntervalSeconds="5"
      ConnectionString="Initial Catalog=WorkflowPersistence;
          Data Source=localhostSQLEXPRESS;
          Integrated Security=SSPI;" />
    </Services>
  </WorkflowRuntime>
</configuration>

That answers the first question. However, that’s not the recommended way to use the standard persistence and tracking services at the same time. Instead, you should use the same database for persistence and tracking. One database means one connection string. And WF provides a special service named SharedConnectionWorkflowCommitWorkBatchService that you should also load. This service is optimized for use with the standard persistence and tracking services. It uses the same database connection for both services, avoiding the use of MSDTC that would otherwise be needed.

Here’s a revised App.config that loads the special commit work batch service and uses the same database for persistence and tracking. Since a single connection string is used for both services, it is moved back to the CommonParameters section of the App.config.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="WorkflowRuntime"
    type="System.Workflow.Runtime.Configuration.WorkflowRuntimeSection,
          System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,
          PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <WorkflowRuntime>
    <CommonParameters>
      <add name="ConnectionString"
      value="Initial Catalog=Workflow;
          Data Source=localhostSQLEXPRESS;
          Integrated Security=SSPI;" />
    </CommonParameters>
    <Services>
      <add type="System.Workflow.Runtime.Hosting.SharedConnectionWorkflowCommitWorkBatchService,
          System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,
          PublicKeyToken=31bf3856ad364e35" />
      <add type="System.Workflow.Runtime.Tracking.SqlTrackingService,
          System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,
          PublicKeyToken=31bf3856ad364e35" />
      <add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService,
          System.Workflow.Runtime, Version=3.0.00000.0,
          Culture=neutral, PublicKeyToken=31bf3856ad364e35"
      UnloadOnIdle="true" LoadIntervalSeconds="5" />
    </Services>
  </WorkflowRuntime>
</configuration>
Categories: workflow

Sample Workflow Persistence chapter

March 19, 2007 Leave a comment

Apress has made Chapter 8 of my Pro WF book available for download in PDF format. This is the chapter that covers workflow persistence. You can obtain this sample chapter from the Apress page for this book, or directly from this site.

Categories: workflow