问题
I have an activity with variables (which are C# expressions), but not able to read their values.
public Collection<Variable> Variables { get; } = new Collection<Variable>();
protected override void DoExecute(NativeActivityContext context)
{
var x = Variables.FirstOrDefault(...).Get(context);
}
resulting in
Activity '1.1: MyActivity' cannot access this variable
because it is declared at the scope of activity '1.1: MyActivity'.
An activity can only access its own implementation variables.
I attempted to expose them via cachemetadata
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.SetImplementationVariablesCollection(Variables);
}
And that results in
Exception <System.NotSupportedException:
Expression Activity type 'CSharpValue`1' requires compilation in order to run.
Please ensure that the workflow has been compiled.
My variables are c# expressions and compiled with
var wwfActivity = ActivityXamlServices.Load(xamlReader, new ActivityXamlServicesSettings {CompileExpressions = true});
回答1:
I was able to hack around it with
var var = context.DataContext.GetProperties()["variableName"];
var value = var.GetValue(context.DataContext) as Whatever;
without overriding the CacheMetadata
method, but it feels a lil weird;
回答2:
I think if you are inside a while loop with a counter in the middle and trying to access a variable like "Number" + i.ToString you will not get the correct answer. It will not evaluate that i.ToString.
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime;
using System.Activities.Validation;
using System.Collections.Generic;
using System.Windows.Markup;
using System.Collections.ObjectModel;
using System.Activities;
namespace WorkflowConsoleApplication2
{
public sealed class CodeActivity1 : CodeActivity
{
// Define an activity input argument of type string
[DefaultValue(null)]
public InArgument<string> Test
{
get;
set;
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
RuntimeArgument textArgument = new RuntimeArgument("Test", typeof(string), ArgumentDirection.In);
metadata.Bind(this.Test, textArgument);
metadata.SetArgumentsCollection(
new Collection<RuntimeArgument>
{
textArgument,
});
}
// If your activity returns a value, derive from CodeActivity<TResult>
// and return the value from the Execute method.
protected override void Execute(CodeActivityContext context)
{
Console.WriteLine(this.Test.Get(context));
}
}
You will need to add that RuntimeArgument to the ArgumentCollection as shown above.
I got this from my answered question : While activity in WF 4 rehosted designer
来源:https://stackoverflow.com/questions/30616844/wf4-an-activity-can-only-access-its-own-implementation-variables