Tuesday, April 28, 2009

How to use EnumerateResourcesActivity in RC0

Last week during my webinar, I wasn't sure how to use the EnumerateResources or EnumerateResourceIteration activities. I thought I'd tie up some loose ends and try to crack this case. Thanks to Henrik and Nima, I was able to get the EnumerateResourcesActivity to work. Turns out that the Iteration activity will be removed from RTM.

Per Henrik's advice, EnumerateResources has the wrong designer, so when you add the activity to a custom workflow, you'll notice that it's closed and you can't add any children to it.



You can work around this by opening the Designer.cs file and adding a code activity to it manually. First, add a CodeActivity to the class:

private CodeActivity codeActivity1;

Next, add the code activity to EnumerateResources in InitializeComponent, before the last line, "this.CanModifyActivities = false;".

#region Workaround
this.codeActivity1 = new System.Workflow.Activities.CodeActivity();
//
// codeActivity1
//

this.codeActivity1.Name = "codeActivity1";
this.codeActivity1.ExecuteCode += new System.EventHandler(this.logIteration);

this.enumerateResourcesActivity1.Activities.Add(this.codeActivity1);
#endregion

Then, create a "logIteration" method in your main class file, and call the GetCurrentIterationItem method from EnumerateResources:

private void logIteration(object sender, EventArgs e)
{
// Log the Resource properties to a string
StringBuilder buffer = new StringBuilder();
buffer.AppendLine("TotalResultsCount : " +
enumerateResourcesActivity1.TotalResultsCount);

ResourceType currentItem = EnumerateResourcesActivity.GetCurrentIterationItem(
(CodeActivity)sender) as ResourceType;

if (currentItem != null)
{
// Resource properties
foreach (KeyValuePair<string, ResourcePropertyInfo> property in currentItem.ResourceProperties)
{
// Attribute name
buffer.Append(property.Key.PadRight(20));
// Attribute type
buffer.Append(property.Value.Type.PadRight(20));
// Value
object val = currentItem[property.Key];
if (val != null)
{
buffer.AppendLine(val.ToString());
}
else
{
buffer.AppendLine();
}
}
}

// Finally, do something with the log message
string output = buffer.ToString();
}

That's it. Don't forget to bind the XPathFilter property on the EnumerateResourcesActivity. Perhaps I'll add an example to our activity library.

Enjoy!

4 comments:

  1. Great you got it working! I hardly can't wait getting a new dev environment so I can start working with this activity!!!

    ReplyDelete
  2. Can you give some more details on how to pass the arguments to the logIteration(object sender, EventArgs e) method. I mean from where do I get the sender object?.. I am very new to FIM and trying to learn few basic stuff..
    Thanks

    ReplyDelete
  3. How do you bind XPathFilter. Do we need a dependencyProperty. or within the Child code activity we can do:
    this.enumerateResourceActivity1.XPathFilter = "/Person";

    ReplyDelete
  4. Great, only one thing, please assign value to all enumerationProperty:

    ActorId
    PageSize (yes eaven to it)
    Selection
    XPathFilter

    In fact I forget to assign value to pagesize and TotalItem give me correct number of item found, but then I could not get each resource and

    "ResourceType currentItem = EnumerateResourcesActivity.GetCurrentIterationItem(
    (CodeActivity)sender) as ResourceType;"

    always give me NULL value.

    Thank you.
    By
    Luka.

    ReplyDelete