Avoiding "An Activity can only get the location of arguments which it owns."
This is a follow-up question to Setting internal properties in co开发者_运维知识库mposite 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?
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);
}
精彩评论