0

VS2012 / .NET 4.5を使用して、(実装の子として)子の受信アクティビティを実装するカスタムアクティビティを作成しています。以下の例では、パラメーターは1つだけに固定されています。Guid型のOutValue。

アクティビティから返す前に、ReceiveDoneを操作して変換する必要があるため、ReceiveDoneの受信パラメーター値の値にアクセスしたいと思います。現在Guidを使用していることを無視してください。それでも、InvalidOperationExceptionを使用して値にアクセスできません。

アクティビティは、所有する引数の場所のみを取得できます。アクティビティ'TestActivity'は、アクティビティ'Wait for Workflow Start Request [InternalforTestActivity]'が所有する引数'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";
}
4

3 に答える 3

0

思いついたことは全部やってみたかもしれませんが、頑固で諦めないので、考え続けました;)

ここでは、代わりに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";
}
于 2013-01-22T12:18:52.717 に答える
0

OutArgumentとそれらを変数に使用する必要があります。ドキュメント付きのコード例を参照してください。

于 2013-01-22T11:26:48.493 に答える
0

内部変数を使用して、内部アクティビティ間で値を渡します。

コードに直接関係しているわけではありませんが、以下の例を参照してください。

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);
于 2013-01-22T11:53:25.167 に答える