简体   繁体   中英

How do I get the strongly-typed value of an OutArgument in code?

Given an Activity (created via the designer) that has several OutArgument properties, is it possible to get their strongly-typed value from a property after invoking the workflow?

The code looks like this:

// generated class
public partial class ActivityFoo : System.Activities.Activity....
{
    ....
    public System.Activities.OutArgument<decimal> Bar { ... }
    public System.Activities.OutArgument<string> Baz { ... }
}

// my class
var activity = new ActivityFoo();
var result = WorkflowInvoker.Invoke(activity);

decimal d = activity.Bar.Get(?)
string s = activity.Baz.Get(?)

The T Get() method on OutArgument<T> that requires an ActivityContext which I'm not sure how to obtain in code.

I also realize it's possible to get the un-typed values from result["Bar"] and result["Baz"] and cast them, but I'm hoping there's another way.

Updated to make it clear there are multiple Out values, although the question would still apply even if there was only one.

If you look at workflows as code, an Activity is no more than a method that receives input arguments and (potentially) returns output arguments.

It happens that Activities allows one to return multiple output arguments, something that C# methods, for example, don't ( actually that's about to change with C# 7 and tuples ).

That's why you've an WorkflowInvoker.Invoke() overload which returns a Dictionary<string, object> because the framework obviously doesn't know what\\how many\\of what type output arguments you have.

Bottom line, the only way for you to do it fully strong-typed is exactly the same way you would be doing on a normal C# method - return one OutArgument of a custom type :

public class ActivityFooOutput
{
    public decimal Bar { get; set }
    public decimal Baz { get; set; }
}

// generated class

public partial class ActivityFoo : System.Activities.Activity....
{
    public System.Activities.OutArgument<ActivityFooOutput> Result { ... }
}

// everything's strongly-typed from here on

var result = WorkflowInvoker.Invoke<ActivityFooOutput>(activity);

decimal d = result.Bar;
string s result.Baz;

Actually, if you don't want to create a custom type for it, you can use said tuples:

// generated

public System.Activities.OutArgument<Tuple<decimal, string>> Result { ... }

// everything's strongly-typed from here on

var result = WorkflowInvoker.Invoke<Tuple<decimal, string>>(activity);

decimal d = result.Item1;
string s result.Item2;

Being the first option obviously more scalable and verbose.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM