3

NativeActivity 内でカスタム C# 式を使用しようとしています

Condition = new CSharpValue("1 == 1")のような単純な式で問題なく動作します

そのような式では機能しませんCondition = new CSharpValue("Address == null")

式のコンパイル エラー「The name 'xxxxx' does not exist in the current context」が原因で、式でアクティビティの Variable または InArgument を参照できません

作業コード

var act = new ExecuteIfTrue
{
    Condition = new CSharpValue<Boolean>("1 == 1"),
    Address = new InArgument<MailAddress>(ctx => new MailAddress { DisplayName = "TestDisplayName" }),
    Body = new WriteLine { Text = "Rest!" }
};

CompileCSharpExpressions<MailAddress>(act);
WorkflowInvoker.Invoke(act);

Non-Working コード (NativeActivity の InArgument を参照)

var act = new ExecuteIfTrue
{
    Condition = new CSharpValue<Boolean>("Address.Email == null"),
    //Condition = new CSharpValue<Boolean>("MailAddressVar == null"),
    Address = new InArgument<MailAddress>(ctx => new MailAddress { DisplayName = "TestDisplayName" }),
    Body = new WriteLine { Text = "Rest!" }
};

CompileCSharpExpressions<MailAddress>(act);
WorkflowInvoker.Invoke(act);

ネイティブ アクティビティ

public class ExecuteIfTrue : NativeActivity
{
    [RequiredArgument]
    public InArgument<bool> Condition { get; set; }

    [RequiredArgument]
    public InArgument<MailAddress> Address { get; set; }

    public Variable<MailAddress> MailAddressVar;

    public Activity Body { get; set; }

    public ExecuteIfTrue()
    {
        MailAddressVar = new Variable<MailAddress> { Default = null };
    }

    protected override void Execute(NativeActivityContext context)
    {
        if (context.GetValue(this.Condition) && this.Body != null)
            context.ScheduleActivity(this.Body);
    }

    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        metadata.AddImplementationVariable(MailAddressVar);
        base.CacheMetadata(metadata);
    }
}


public class MailAddress
{
    public String Email { get; set; }
    public String DisplayName { get; set; }
}

ヘルパー メソッド

public static void CompileCSharpExpressions<T>(Activity activity)
{
    var impl = new AttachableMemberIdentifier(typeof(TextExpression), "NamespacesForImplementation");
    var namespaces = new List<string> { typeof(T).Namespace };
    TextExpression.SetReferencesForImplementation(activity, new AssemblyReference { Assembly = typeof(T).Assembly });
    AttachablePropertyServices.SetProperty(activity, impl, namespaces);

    var activityName = activity.GetType().ToString();
    var activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
    var activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());

    var settings = new TextExpressionCompilerSettings
    {
        Activity = activity,
        Language = "C#",
        ActivityName = activityType,
        ActivityNamespace = activityNamespace,
        RootNamespace = null,
        GenerateAsPartialClass = false,
        AlwaysGenerateSource = true,
        ForImplementation = false
    };

    var results = new TextExpressionCompiler(settings).Compile();

    if (results.HasErrors)
    {
        throw new Exception("Compilation failed.");
    }

    var compiledExpressionRoot = Activator.CreateInstance(results.ResultType, new object[] { activity }) as ICompiledExpressionRoot;
    CompiledExpressionInvoker.SetCompiledExpressionRoot(activity, compiledExpressionRoot);
}
4

1 に答える 1

1

エラーはかなり明白です。式のスコープに変数がありませんMailAddressVar

その理由は、変数を式に渡す必要があるためです。ExecuteIfTrueアクティビティに変数パラメーターがありません。

代わりに、次のようにしてみてください。

Variable<string> mailAddressVar = new Variable<string>(name: "MailAddressVar", defaultValue: null);

Activity seq = new Sequence
{
    Variables = { mailAddressVar },
    Activities = 
    {
        new ExecuteIfTrue
        {       
            //Condition = new CSharpValue<Boolean>("Address.Email == null"),
            Condition = new CSharpValue<Boolean>("MailAddressVar == null"),
            Address = new InArgument<MailAddress>(ctx => new MailAddress { DisplayName = "TestDisplayName" }),
            Body = new WriteLine { Text = "Rest!" }
        }
    }
};

ExecuteIfTrue.CompileCSharpExpressions<MailAddress>(seq);
WorkflowInvoker.Invoke(seq);
于 2015-09-02T14:22:31.623 に答える