简体   繁体   English

在WF 4.5中无法使用CSharpValue表达式访问词典

[英]Unable to access Dictionary using CSharpValue expression in WF 4.5

I have tried to create workflow using code as explained here . 我尝试使用此处说明的代码创建工作流。 But I can't get through my result. 但是我无法取得结果。 I have created Console Application with Class1.cs containing my workflow code and Program.cs which the workflow is hosted in WorkflowApplication class including inputs. 我创建了带有Class1.cs的控制台应用程序,其中包含我的工作流代码和Program.cs,该工作流托管在WorkflowApplication类中,包括输入。 while executing the unhandled exception occurs with the message "Expression Activity type 'CSharpValue`1' requires compilation in order to run. Please ensure that the workflow has been compiled" . 在执行未处理的异常时,出现消息“表达式活动类型'CSharpValue`1'需要进行编译才能运行。请确保已编译工作流程” But also I have included the method CompileExpressions for compiling, as said here . 而且我已经包括用于编译方法CompileExpressions,如说在这里 I appreciate in advance for your help! 预先感谢您的帮助!

ReverseStringWorkflow.cs ReverseStringWorkflow.cs

 public class ReverseStringWorkflow : Activity
    {
        public InArgument<Dictionary<string,object>> StringToReverse { get; set; } 

        protected override Func<Activity> Implementation
        {
            get
            {
                return () =>
                {
                    Sequence sequence = new Sequence
                    {
                        Activities =
                        {
                             new WriteLine
                             {
                                 Text = new CSharpValue<string>("StringToReverse[\"name\"].ToString()")

                             }
                        }
                    };
                    return sequence;
                };
            }
            set
            {
                base.Implementation = value;
            }

        }
    }

Program.cs Program.cs

class Program
    {
        static void Main(string[] args)
        {
            Activity workflow2 = new ReverseStringWorkflow();
            Dictionary<string, object> mainInputs = new Dictionary<string, object>();
            Dictionary<string, object> subInputs = new Dictionary<string, object>();                
            subInputs.Add("name","name123");
            mainInputs.Add("StringToReverse", subInputs);
            WorkflowApplication app = new WorkflowApplication(workflow2, mainInputs);
            app.OnUnhandledException = delegate (WorkflowApplicationUnhandledExceptionEventArgs e)
            {
                Console.WriteLine("Error occurred");
                return UnhandledExceptionAction.Terminate;
            };
            CompileExpressions(workflow2);

            app.Run();

            Console.ReadLine();
        }
        public static void CompileExpressions(Activity activity)
        {
            // activityName is the Namespace.Type of the activity that contains the
            // C# expressions.
            string activityName = activity.GetType().ToString();

            // Split activityName into Namespace and Type.Append _CompiledExpressionRoot to the type name
            // to represent the new type that represents the compiled expressions.
            // Take everything after the last . for the type name.
            string activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
            // Take everything before the last . for the namespace.
            string activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());

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

            // Compile the C# expression.
            TextExpressionCompilerResults results =
                new TextExpressionCompiler(settings).Compile();

            // Any compilation errors are contained in the CompilerMessages.
            if (results.HasErrors)
            {
                throw new Exception("Compilation failed.");
            }

            // Create an instance of the new compiled expression type.
            ICompiledExpressionRoot compiledExpressionRoot =
                Activator.CreateInstance(results.ResultType,
                    new object[] { activity }) as ICompiledExpressionRoot;

            // Attach it to the activity.
            CompiledExpressionInvoker.SetCompiledExpressionRoot(
                activity, compiledExpressionRoot);
        }
    }

Full Error Message: 完整的错误消息:

[System.NotSupportedException]  {System.NotSupportedException: Expression Activity type 'CSharpValue`1' requires compilation in order to run.  Please ensure that the workflow has been compiled.
   at System.Activities.Expressions.CompiledExpressionInvoker.InvokeExpression(ActivityContext activityContext)
   at Microsoft.CSharp.Activities.CSharpValue`1.Execute(CodeActivityContext context)
   at System.Activities.CodeActivity`1.InternalExecuteInResolutionContext(CodeActivityContext context)
   at System.Activities.Runtime.ActivityExecutor.ExecuteInResolutionContext[T](ActivityInstance parentInstance, Activity`1 expressionActivity)
   at System.Activities.InArgument`1.TryPopulateValue(LocationEnvironment targetEnvironment, ActivityInstance activityInstance, ActivityExecutor executor)
   at System.Activities.RuntimeArgument.TryPopulateValue(LocationEnvironment targetEnvironment, ActivityInstance targetActivityInstance, ActivityExecutor executor, Object argumentValueOverride, Location resultLocation, Boolean skipFastPath)
   at System.Activities.ActivityInstance.InternalTryPopulateArgumentValueOrScheduleExpression(RuntimeArgument argument, Int32 nextArgumentIndex, ActivityExecutor executor, IDictionary`2 argumentValueOverrides, Location resultLocation, Boolean isDynamicUpdate)
   at System.Activities.ActivityInstance.ResolveArguments(ActivityExecutor executor, IDictionary`2 argumentValueOverrides, Location resultLocation, Int32 startIndex)
   at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)

Thank You Mr. Maciej Los. 谢谢Maciej Los先生。 Finally I got the right approach from the article you referred, your reply was very helpful.. 最终,我从您引用的文章中找到了正确的方法,您的回复非常有帮助。

Here is the answer if someone needs in future. 如果有人将来需要,这是答案。

 static void Main(string[] args)
        {
            Dictionary<string, object> inputs = new Dictionary<string, object>();            
            inputs.Add("userName", "Test User");         

            // Using DynamicActivity for this sample so that we can have an
            // InArgument, and also do everything without XAML at all
            DynamicActivity codeWorkflow = new DynamicActivity();
            codeWorkflow.Name = "MyScenario.MyDynamicActivity";
            foreach (var key in inputs.Keys)
            {
                DynamicActivityProperty property = new DynamicActivityProperty();
                property.Name = key;
                property.Type = typeof(InArgument<Dictionary<string,object>>);                
                codeWorkflow.Properties.Add(property);
            }
            codeWorkflow.Implementation = () => new WriteLine
            {
                Text = new CSharpValue<string>
                {
                    ExpressionText = "\"hello ! \" + InArguments[\"userName\"].ToString()"
                },
            };         
            Compile(codeWorkflow);
            WorkflowInvoker.Invoke(codeWorkflow,
             new Dictionary<string, object>
                {
            { "InArguments", inputs}
                });

            Console.ReadLine(); 
        }

And compile method is: 编译方法是:

static void Compile(DynamicActivity dynamicActivity)
        {
            TextExpressionCompilerSettings settings = new TextExpressionCompilerSettings
            {
                Activity = dynamicActivity,
                Language = "C#",
                ActivityName = dynamicActivity.Name.Split('.').Last() + "_CompiledExpressionRoot",
                ActivityNamespace = string.Join(".", dynamicActivity.Name.Split('.').Reverse().Skip(1).Reverse()),
                RootNamespace = null,
                GenerateAsPartialClass = false,
                AlwaysGenerateSource = true,
            };

            TextExpressionCompilerResults results =
                new TextExpressionCompiler(settings).Compile();
            if (results.HasErrors)
            {
                throw new Exception("Compilation failed.");
            }

            ICompiledExpressionRoot compiledExpressionRoot =
                Activator.CreateInstance(results.ResultType,
                    new object[] { dynamicActivity }) as ICompiledExpressionRoot;
            CompiledExpressionInvoker.SetCompiledExpressionRootForImplementation(
                dynamicActivity, compiledExpressionRoot);
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 WF 4.5.1表达式活动类型&#39;CSharpValue`1&#39;需要进行编译才能运行 - WF 4.5.1 Expression Activity type 'CSharpValue`1' requires compilation in order to run Workflow Foundation 4.5“表达式活动类型&#39;CSharpValue`1&#39;需要编译才能运行。” - Workflow Foundation 4.5 “Expression Activity type 'CSharpValue`1' requires compilation in order to run.” WF 4.5。 使用带外部类引用的C#表达式 - WF 4.5. Using C# expressions with external class references WF 4.5:是否可以在运行时动态添加变量? - WF 4.5: Is it possible to add variables dynamically at runtime? Windows WF 4.5中集合的真正并发 - True concurrency on a collection in Windows WF 4.5 WPF WF4.5重新托管的设计器内存问题 - WPF WF4.5 Rehosted Designer Memory Issues WF4.5不编译并行的C#工作流程 - WF4.5 not compiling side-by-side c# workflows 表到字典 <String,Object> 使用Lambda表达式 - Table To Dictionary <String,Object> using Lambda Expression 如何在wf 4.5中使用自动环绕序列设计器创建工作流程活动? - How to create a workflow activity with auto-surround sequence designer in wf 4.5? 在运行时使用WF4.5将现有工作流程包装在try / catch活动中 - Wrap an existing workflow in a try/catch activity at run-time with WF4.5
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM