[英]Accessing OutArgument value of Receive implementation child activity within custom WF4 activity
使用VS2012 / .NET 4.5,我正在創建一個自定義活動,該活動實現了Receive子活動(作為實現子項)。 在下面的示例中,參數僅固定為一個:Guid類型的OutValue。
我真的很想在ReceiveDone中訪問傳入參數的值,因為我需要使用它並對其進行轉換,然后再從活動返回它。 請忽略我當前正在使用Guid,它仍然無法通過和InvalidOperationException訪問值:
活動只能獲取其擁有的參數的位置。 活動“ TestActivity”正試圖獲取活動“等待工作流啟動請求[TestActivity內部]”所擁有的參數“ OutValue”的位置
我已經嘗試了所有我能想到的,但是感到震驚。 一定有辦法做到這一點很簡單嗎?
public class TestActivity : NativeActivity<Guid>
{
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
var content = ReceiveParametersContent.Create(new Dictionary<string, OutArgument>()
{
// How to access the runtime value of this inside TestActivity?
{"OutValue", new OutArgument<Guid>()}
});
startReceiver = new Receive()
{
DisplayName = string.Format("Wait for workflow start request [Internal for {0}]", this.DisplayName),
CanCreateInstance = true,
ServiceContractName = XName.Get("IStartService", Namespace),
OperationName = "Start",
Content = content
};
foreach (KeyValuePair<string, OutArgument> keyValuePair in content.Parameters)
{
metadata.AddImportedChild(keyValuePair.Value.Expression);
}
metadata.AddImplementationChild(startReceiver);
}
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(startReceiver, ReceiveDone);
}
private void ReceiveDone(NativeActivityContext context, ActivityInstance completedInstance)
{
var receive = completedInstance.Activity as Receive;
ReceiveParametersContent content = receive.Content as ReceiveParametersContent;
try
{
// This causes InvalidOperationException.
// An Activity can only get the location of arguments which it owns.
// Activity 'TestActivity' is trying to get the location of argument 'OutValue'
// which is owned by activity 'Wait for workflow start request [Internal for TestActivity]'
var parmValue = content.Parameters["OutValue"].Get(context);
}
catch (Exception)
{ }
}
private Receive startReceiver;
private const string Namespace = "http://company.namespace";
}
您需要使用OutArgument及其變量。 請參閱文檔中的代碼示例。
使用內部變量在內部活動之間傳遞值。
盡管與您的代碼沒有直接關系,但請參見下面的示例,該示例應為您提供了思路:
public sealed class CustomNativeActivity : NativeActivity<int>
{
private Variable<int> internalVar;
private Assign<int> internalAssign;
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
internalVar = new Variable<int>("intInternalVar", 10);
metadata.AddImplementationVariable(internalVar);
internalAssign = new Assign<int>
{
To = internalVar,
Value = 12345
};
metadata.AddImplementationChild(internalAssign);
}
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(internalAssign, (activityContext, instance) =>
{
// Use internalVar value, which was seted by previous activity
var value = internalVar.Get(activityContext);
Result.Set(activityContext, value);
});
}
}
調用以上活動:
WorkflowInvoker.Invoke<int>(new CustomNativeActivity());
將輸出:
12345
編輯:
在您的情況下,您的OutArgument將為internalVar
new OutArgument<int>(internalVar);
我可能已經嘗試了所有我想過的東西,但是我很固執,拒絕放棄,所以我一直在思考;)
我在這里更改了示例,改為使用Data類作為參數(它本身不會更改任何內容,但在我的實際示例中需要這樣做)。
下面的代碼現在是有關如何訪問傳入數據的有效示例。 實現變量的使用是關鍵:
runtimeVariable = new Variable<Data>();
metadata.AddImplementationVariable(runtimeVariable);
和OutArgument:
new OutArgument<Data>(runtimeVariable)
然后,我可以使用以下方法訪問值:
// Here dataValue will get the incoming value.
var dataValue = runtimeVariable.Get(context);
我沒有在其他地方看到過一個例子,正是這個例子。 希望對我以外的任何人都有用。
編碼:
[DataContract]
public class Data
{
[DataMember]
Guid Property1 { get; set; }
[DataMember]
int Property2 { get; set; }
}
public class TestActivity : NativeActivity<Guid>
{
public ReceiveContent Content { get; set; }
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
runtimeVariable = new Variable<Data>();
metadata.AddImplementationVariable(runtimeVariable);
Content = ReceiveParametersContent.Create(new Dictionary<string, OutArgument>()
{
{"OutValue", new OutArgument<Data> (runtimeVariable)}
});
startReceiver = new Receive()
{
DisplayName = string.Format("Wait for workflow start request [Internal for {0}]", this.DisplayName),
CanCreateInstance = true,
ServiceContractName = XName.Get("IStartService", Namespace),
OperationName = "Start",
Content = Content
};
metadata.AddImplementationChild(startReceiver);
}
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(startReceiver, ReceiveDone);
}
private void ReceiveDone(NativeActivityContext context, ActivityInstance completedInstance)
{
// Here dataValue will get the incoming value.
var dataValue = runtimeVariable.Get(context);
}
private Receive startReceiver;
private Variable<Data> runtimeVariable;
private const string Namespace = "http://company.namespace";
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.