I have created a Native activity and I need to call another activity on a Bookmark Resume call. My First Activity name is "Apply" and Second activity is called "Approve". In Apply, i have created a property as below.
public Approve Approve
{
get;
set;
}
and then I have registered the CacheMetadata as below.
metadata.AddImplementationChild(this.Approve);
base.CacheMetadata(metadata);
And then "OnResumeBookmark" method, Im scheduling it.
this.Approve = new Approve();
this.Approve.ID = context.GetValue(this.ID);
OutArgument<string> res = this.Approve.Result;
context.ScheduleActivity(this.Approve);
But When it runs, it gives me the below error.
The provided activity was not part of this workflow definition when its metadata was being processed. The problematic activity named 'Approve' was provided by the activity named 'Apply'.
Could you please help me to resolve this?
There are two approaches to activity development:
- The Private Implementation Route
- The Public Implementation Route
It appears you are working on the private implementation strategy from your question, but I'll provide sample code for both ways below.
The Private Implementation Way
In this approach, the Apply
activity is responsible for setting up everything about the Approve
child activity. We wire up the ID
property using the WF Variable<string>
object. Also, we inform the WF run time that the Approve
activity can be scheduled by the Apply
activity, just like you have in your code sample.
public class Approve : CodeActivity
{
public InArgument<string> Something
{
get; set;
}
protected override void Execute(CodeActivityContext context)
{
var message = string.Format("Approval of {0} in process... please wait.", this.Something.Get(context));
Console.WriteLine(message);
}
}
public class Apply : NativeActivity
{
private readonly Approve approve;
private readonly Variable<string> thingToApproveVar;
public Apply()
{
this.thingToApproveVar = new Variable<string>();
this.approve = new Approve();
this.approve.Something = new InArgument<string>(this.thingToApproveVar);
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.AddImplementationVariable(this.thingToApproveVar);
metadata.AddImplementationChild(this.approve);
}
protected override void Execute(NativeActivityContext context)
{
Console.WriteLine("Approving...");
this.thingToApproveVar.Set(context, "Hello");
context.ScheduleActivity(this.approve, this.OnApprovalCompleted);
}
private void OnApprovalCompleted(NativeActivityContext activityContext, ActivityInstance instance)
{
Console.WriteLine("Apply succeeded!");
}
}
The Public Implementation Way
The second approach in developing your activity is to define your Apply
activity to simply schedule the Approve
activity. The CacheMetadata
method needs a slight tweak for this though, by using the AddChild
method instead of the AddImplementationChild
method.
public class Apply : NativeActivity
{
public Apply()
{
}
public Approve Approve { get; set; }
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.AddChild(this.Approve);
}
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(this.Approve, this.OnApprovalCompleted);
}
private void OnApprovalCompleted(NativeActivityContext activityContext, ActivityInstance instance)
{
Console.WriteLine("Apply succeeded!");
}
}
And to execute the "public implementation way", it would look like the following:
class Program
{
static void Main(string[] args)
{
WorkflowInvoker.Invoke(new Sequence()
{
Activities =
{
new Apply()
{
Approve = new Approve()
{
Something = "Hello World!"
}
}
}
});
}
}