3

This is a follow-up question to Setting internal properties in composite WF4 Activities at design time.

I am creating a composite Windows Workflow Activity (under .NET 4) that contains Receive and SendReply Activities with some of the properties predefined. This is a NativeActivity, not an Activity Template. (See @Maurice's reply to the above question for an example.)

If I attempt to set an InArgument associated with the internal SendReply from Execute (using the parent's context), I get an InvalidOperationException:

An Activity can only get the location of arguments which it owns. Activity 'CreateInstance' is trying to get the location of argument 'Parameter0' which is owned by activity 'SendReply'.

In my case I'm trying to set a CorrelationHandle, but I believe this would affect SendParametersContent Parameters as well. How can I work around this?

1 Answer 1

4

Here is an update version of the CacheMetadata that stores the input argument in a variable and uses it in the response and sets the CorrelationHandle. The basic trick is to add the them as Variable using the AddImplementationVariable, because the activities are added using AddImplementationChild.

protected override void CacheMetadata(NativeActivityMetadata metadata)
{
    _receive = _receive ?? new Receive();
    _sendReply = _sendReply ?? new SendReply();
    _receive.CanCreateInstance = true;
    metadata.AddImplementationChild(_receive);
    metadata.AddImplementationChild(_sendReply);

    _receive.ServiceContractName = ServiceContractName;
    _receive.OperationName = OperationName;

    var correlationHandle = new Variable<CorrelationHandle>("correlationHandle");
    metadata.AddImplementationVariable(correlationHandle);
    var correlationInitializer = new RequestReplyCorrelationInitializer()
    {
        CorrelationHandle = new InArgument<CorrelationHandle>(correlationHandle)
    };
    _receive.CorrelationInitializers.Add(correlationInitializer);


    var firstName = new Variable<string>("firstName");
    metadata.AddImplementationVariable(firstName);
    var args = new ReceiveParametersContent();
    args.Parameters["firstName"] = new OutArgument<string>(firstName);
    _receive.Content = args;


    _sendReply.Request = _receive;
    var results = new SendParametersContent();
    results.Parameters["greeting"] = new InArgument<string>(new VisualBasicValue<string>("\"Hello \" & firstName"));
    _sendReply.Content = results;

    base.CacheMetadata(metadata);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Excellent; thank you! I made the generic Variables private fields so I could access them in the Execute method. I found that Set(context, correlationHandle) does not work; "The operation cannot be performed on variables of Handle subtypes." I reworked my logic so that CorrelationHandle was an InArgument, which succeeded. (I'm using a QueryCorrelationInitializer rather than a RequestReply.)
This seems to have changed under 4.5. You'll get the dreaded "One or more children have validation errors."

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.