WF 4.5.1表达活动类型' CSharpValue`1'需要编译才能运行

时间:2014-11-21 13:50:21

标签: c# .net workflow-foundation

我正在尝试运行某个活动,但是我在运行时收到此错误:

表达式活动类型'CSharpValue`1'需要编译才能运行。请确保已编译工作流程。

查看单位测试输出我看到了:

30: WorkflowInstance "PatriarchActivity" Unhandled Exception Source "Assign<SortedList<IntContainer,SimpleData>>" Exception <System.NotSupportedException: Expression Activity type 'CSharpValue`1' requires compilation in order to run.  Please ensure that the workflow has been compiled.

编译似乎运行正常。

我使用此页面中的代码来编译工作流程: http://msdn.microsoft.com/en-us/library/jj591618%28v=vs.110%29.aspx#CodeWorkflows

我不知道问题是什么,并且消息没有帮助,因为错误在于imho。是的,得到它,还没有编译,然后我该如何编译呢?

非常感谢您的解释。

我正在使用带有.net 4.5.1的visual 2013 update 4

这是一个小测试案例,我希望能够正确地突出问题。

namespace WFCS
{
    public sealed class ActivityCompiler 
    {
        private static readonly ActivityCompiler instance_ = new ActivityCompiler();

            public static ActivityCompiler Instance
            {
                get
                {
                    return instance_;
                }
            }

            public SimpleActivity GetSimpleActivity()
            {
                SimpleActivity act = new SimpleActivity();
                AttachableMemberIdentifier impl = new AttachableMemberIdentifier(typeof(TextExpression), "Namespaces");
                AttachablePropertyServices.SetProperty(act, impl, ActivityCompiler.Instance.GetSimpleActivityNameSpaceList());
                TextExpression.SetReferencesForImplementation(act, ActivityCompiler.Instance.GetSimpleActivityAssemblyReferenceList().ToList());
                ActivityCompiler.Instance.Compile(act);
                return act;
            }


            public Boolean Compile(Activity aActivity)
            {
                try
                {
                    // activityName is the Namespace.Type of the activity that contains the
                    // C# expressions.
                    string activityName = aActivity.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 = aActivity,
                        Language = "C#",
                        ActivityName = activityType,
                        ActivityNamespace = activityNamespace,
                        RootNamespace = "CSharpExpression",
                        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[] { aActivity }) as ICompiledExpressionRoot;

                    // Attach it to the activity.
                    CompiledExpressionInvoker.SetCompiledExpressionRoot(
                        aActivity, compiledExpressionRoot);
                }
                catch (Exception e)
                {
                    string err = e.ToString();
                    return false;
                }
                return true;
            }


            public Boolean CompileDynamicActivity(Activity aDynamicActivity)
            {
                try
                {
                    // activityName is the Namespace.Type of the activity that contains the
                    // C# expressions.
                    string activityName = aDynamicActivity.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 = aDynamicActivity,
                        Language = "C#",
                        ActivityName = activityType,
                        ActivityNamespace = activityNamespace,
                        RootNamespace = "CSharpExpression",
                        GenerateAsPartialClass = false,
                        AlwaysGenerateSource = true,
                        ForImplementation = true
                    };

                    // 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 in ActivityCompiler");
                    }

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

                    // Attach it to the activity.
                    CompiledExpressionInvoker.SetCompiledExpressionRootForImplementation(
                        aDynamicActivity, compiledExpressionRoot);
                }
                catch (Exception e)
                {
                    string err = e.ToString();
                    throw e ;
                }
                return true;
            }

            private HashSet<AssemblyReference> GetSimpleActivityAssemblyReferenceList()
            {
                HashSet<AssemblyReference> ass = new HashSet<AssemblyReference>();
                ass.Add(new AssemblyReference { Assembly = typeof(StringContainer).Assembly, AssemblyName = typeof(StringContainer).Assembly.GetName() });
                ass.Add(new AssemblyReference { Assembly = typeof(IntContainer).Assembly, AssemblyName = typeof(IntContainer).Assembly.GetName() });
                ass.Add(new AssemblyReference { Assembly = typeof(System.Runtime.Serialization.IExtensibleDataObject).Assembly, AssemblyName = typeof(IExtensibleDataObject).Assembly.GetName() });
                return ass;
            }

            private HashSet<String> GetSimpleActivityNameSpaceList()
            {
                HashSet<String> ns = new HashSet<String>();
                ns.Add(typeof(StringContainer).Namespace);
                ns.Add(typeof(IntContainer).Namespace);
                return ns;
            }

            public MotherActivity GetMotherActivity()
            {
                MotherActivity act = new MotherActivity();
                AttachableMemberIdentifier impl = new AttachableMemberIdentifier(typeof(TextExpression), "NamespacesForImplementation");
                AttachablePropertyServices.SetProperty(act, impl, ActivityCompiler.Instance.GetMotherActivityNameSpaceList());
                TextExpression.SetReferencesForImplementation(act, ActivityCompiler.Instance.GetMotherActivityAssemblyReferenceList().ToList());
                ActivityCompiler.Instance.CompileDynamicActivity(act);
                return act;
            }

            private HashSet<AssemblyReference> GetMotherActivityAssemblyReferenceList()
            {
                HashSet<AssemblyReference> ass = new HashSet<AssemblyReference>();
                ass.UnionWith(ActivityCompiler.Instance.GetSimpleActivityAssemblyReferenceList());
                ass.Add(new AssemblyReference { Assembly = typeof(System.Runtime.Serialization.IExtensibleDataObject).Assembly, AssemblyName = typeof(IExtensibleDataObject).Assembly.GetName() });
                return ass;
            }

            private HashSet<String> GetMotherActivityNameSpaceList()
            {
                HashSet<String> ns = new HashSet<String>();
                ns.UnionWith(ActivityCompiler.Instance.GetSimpleActivityNameSpaceList());
                return ns;
            }

            public PatriarchActivity GetPatriarchActivity()
            {
                PatriarchActivity act = new PatriarchActivity();
                AttachableMemberIdentifier impl = new AttachableMemberIdentifier(typeof(TextExpression), "NamespacesForImplementation");
                AttachablePropertyServices.SetProperty(act, impl, ActivityCompiler.Instance.GetPatriarchActivityNameSpaceList());
                TextExpression.SetReferencesForImplementation(act, ActivityCompiler.Instance.GetPatriarchActivityAssemblyReferenceList().ToList());
                ActivityCompiler.Instance.CompileDynamicActivity(act);
                return act;
            }

            private HashSet<AssemblyReference> GetPatriarchActivityAssemblyReferenceList()
            {
                HashSet<AssemblyReference> ass = new HashSet<AssemblyReference>();
                ass.UnionWith(ActivityCompiler.Instance.GetMotherActivityAssemblyReferenceList());
                return ass;
            }

            private HashSet<String> GetPatriarchActivityNameSpaceList()
            {
                HashSet<String> ns = new HashSet<String>();
                ns.UnionWith(ActivityCompiler.Instance.GetMotherActivityNameSpaceList());
                return ns;
            }
    }
}




namespace WFCS
{
    [DataContract]
    public class IntContainer : IComparable
    {
        [DataMember]
        public Int32 Value;

        public IntContainer(int aInt32)
        {
            this.Value = aInt32;
        }

        public int CompareTo(object obj)
        {
            return this.Value.CompareTo(((IntContainer)obj).Value);
        }
    }
}



namespace WFCS
{
    public class MotherActivity : Activity
    {
        [RequiredArgument]
        public InArgument<IntContainer> IntToAdd { get; set; }

        [RequiredArgument]
        public InArgument<SortedList<IntContainer, SimpleData>> DataToProcess { get; set; }

        [RequiredArgument]
        public OutArgument<SortedList<IntContainer, SimpleData>> ProcessedData { get; set; }


        private DelegateInArgument<SimpleData> simpleDataIterator;
        private Variable<SimpleData> wfvar_tmpsimpledata;
        private SimpleData native_tmpsimpledata;

        protected override Func<Activity> Implementation
        {
            get
            {
                return () =>
                {
                    Sequence seq = new Sequence
                    {
                        Variables =
                        {

                        },
                        Activities = 
                        {
                            new WriteLine
                            {
                                Text = new InArgument<String>((env) => "I'm entering the mother activity processing nb = " + DataToProcess.Get(env).Count)
                            },
                            new Assign<SortedList<IntContainer, SimpleData>>
                            {
                                To = new CSharpReference<SortedList<IntContainer, SimpleData>>("ProcessedData"),
                                Value = new CSharpValue<SortedList<IntContainer, SimpleData>>("new SortedList<IntContainer, SimpleData>()"),
                            },
                            new ForEach<SimpleData>
                            {
                                Values = new InArgument<IEnumerable<SimpleData>>((env) => (IList<SimpleData>)DataToProcess.Get(env).Values),
                                Body = new ActivityAction<SimpleData>()
                                {
                                     Argument = simpleDataIterator,
                                     Handler = new Sequence()
                                     {
                                         Variables = 
                                         {
                                              wfvar_tmpsimpledata
                                         },

                                         Activities = 
                                         {
                                             new Assign<SimpleData>
                                             {
                                                 To = new CSharpReference<SimpleData>("WFVAR_tmpsimpledata"),
                                                 Value = new InArgument<SimpleData>((env) => simpleDataIterator.Get(env))
                                             },
                                             new SimpleActivity
                                             {
                                                  IntContainer = new CSharpValue<IntContainer>("new WFCS.IntContainer(IntToAdd.Value + WFVAR_tmpsimpledata.ID.Value);"),
                                                  StringContainer = new CSharpValue<StringContainer>("new WFCS.StringContainer(\"toto\");"),
                                                  Result = new CSharpReference<SimpleData>("WFVAR_tmpsimpledata")
                                             },
                                             new AddToCollection<KeyValuePair<IntContainer, SimpleData>>
                                             {
                                                 Collection = new InArgument<ICollection<KeyValuePair<IntContainer,SimpleData>>>((env) => ProcessedData.Get(env)),
                                                 Item = new InArgument<KeyValuePair<IntContainer, SimpleData>>( (env) => (new KeyValuePair<IntContainer, SimpleData>(wfvar_tmpsimpledata.Get(env).ID, 
                                                                                                                                                                     wfvar_tmpsimpledata.Get(env))))
                                             }
                                         }
                                     }
                                }
                            }
                        }

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


        public MotherActivity()
        {
            simpleDataIterator = new DelegateInArgument<SimpleData>();
            native_tmpsimpledata = new SimpleData(0, "notset");
            wfvar_tmpsimpledata = new Variable<SimpleData>("WFVAR_tmpsimpledata", ctx => native_tmpsimpledata);
        }


    }
}


namespace WFCS
{
    public class PatriarchActivity : Activity
    {
        // remove this "fake" input
        //[RequiredArgument]
        //public InArgument<SortedList<IntContainer, SimpleData>> DataToProcess { get; set; }

        [RequiredArgument]
        public OutArgument<SortedList<IntContainer, SimpleData>> ProcessedData { get; set; }

        IntContainer native_intcontainer;
        Variable<IntContainer> wfvar_intcontainer;
        SortedList<IntContainer, SimpleData> native_dataToProcess;
        Variable<SortedList<IntContainer, SimpleData>> wfvar_dataToProcess;

        protected override Func<Activity> Implementation
        {
            get
            {
                return () => 
                {
                    Sequence seq = new Sequence
                    {
                        Variables =
                        {
                            wfvar_intcontainer, wfvar_dataToProcess
                        },
                        Activities = 
                        { 
                            new Assign<SortedList<IntContainer, SimpleData>>
                            {
                                To = new CSharpReference<SortedList<IntContainer, SimpleData>>("WFVAR_dataToProcess"),
                                Value = new CSharpValue<SortedList<IntContainer, SimpleData>>("new SortedList<IntContainer, SimpleData>()"),
                            },
                            new Assign<SortedList<IntContainer, SimpleData>>
                            {
                                To = new CSharpReference<SortedList<IntContainer, SimpleData>>("ProcessedData"),
                                Value = new CSharpValue<SortedList<IntContainer, SimpleData>>("new SortedList<IntContainer, SimpleData>()"),
                            },
                            new AddToCollection<KeyValuePair<IntContainer, SimpleData>>
                            {
                                Collection = wfvar_dataToProcess,
                                Item = new InArgument<KeyValuePair<IntContainer, SimpleData>>( (env) => (new KeyValuePair<IntContainer, SimpleData>(new IntContainer(1), 
                                                                                                                                                    new SimpleData(1, "toto"))))
                            },
                            new AddToCollection<KeyValuePair<IntContainer, SimpleData>>
                            {
                                Collection = wfvar_dataToProcess,
                                Item = new InArgument<KeyValuePair<IntContainer, SimpleData>>( (env) => (new KeyValuePair<IntContainer, SimpleData>(new IntContainer(2), 
                                                                                                                                                    new SimpleData(2, "titi"))))
                            },
                            new WriteLine
                            {
                                Text = new InArgument<String>((env) => "I'm in the patriarch activity processing nb = " + wfvar_dataToProcess.Get(env).Count)
                            },
                            new MotherActivity
                            {
                                IntToAdd = new CSharpValue<IntContainer>("WFVAR_intcontainer"),
                                DataToProcess = new CSharpValue<SortedList<IntContainer, SimpleData>>("WFVAR_dataToProcess"),
                                ProcessedData = new CSharpReference<SortedList<IntContainer,SimpleData>>("ProcessedData")
                            }
                        }
                    };
                    return seq;
                };
            }
            set
            {
                base.Implementation = value;
            }
        }


        public PatriarchActivity()
        {
            native_intcontainer = new IntContainer(42);
            wfvar_intcontainer = new Variable<IntContainer>("WFVAR_intcontainer", ctx => native_intcontainer);

            //native_dataToProcess = new SortedList<IntContainer, SimpleData>();
            //wfvar_dataToProcess = new Variable<SortedList<IntContainer, SimpleData>>("WFVAR_dataToProcess", ctx => native_dataToProcess);

            wfvar_dataToProcess = new Variable<SortedList<IntContainer, SimpleData>>("WFVAR_dataToProcess");

        }

    }
}


namespace WFCS
{
    public class SimpleActivity : NativeActivity<SimpleData>
    {
        [RequiredArgument]
        public InArgument<StringContainer> StringContainer { get; set; }

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

        protected override void Execute(NativeActivityContext context)
        {
            this.Result.Set(context, new SimpleData(context.GetValue(IntContainer).Value,
                                                    context.GetValue(StringContainer).Value));
        }
    }
}



namespace WFCS
{
    [DataContract]
    public class SimpleData
    {
        [DataMember]
        public IntContainer ID;
        [DataMember]
        public StringContainer Str;

        public SimpleData(Int32 aInt32, String aString)
        {
            ID = new IntContainer(aInt32);
            Str = new StringContainer(aString);
        }
    }
}

namespace WFCS
{
    [DataContract]
    public class StringContainer
    {
        [DataMember]
        public String Value;

        public StringContainer(string aString)
        {
            this.Value = aString;
        }
    }
}

和单元测试对应这三个活动:(需要Microsoft ..Activities.UnitTesting NuGet包)

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WFCS;
using Microsoft.Activities.UnitTesting;

namespace WFCSTest
{
    [TestClass]
    public class SimpleActivityTest
    {
        [TestMethod]
        public void TestSimpleActivity1()
        {
            SimpleActivity activity = ActivityCompiler.Instance.GetSimpleActivity();
            WorkflowInvokerTest host = WorkflowInvokerTest.Create(activity);
            host.InArguments.StringContainer = new StringContainer("Jesus");
            host.InArguments.IntContainer = new IntContainer(42);
            try
            {
                host.TestActivity();
                SimpleData res = host.OutArguments.Result;
                Assert.AreEqual(res.ID.Value, 42);
            }
            finally
            {
                host.Tracking.Trace();
            }
        }
    }
}

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WFCS;
using Microsoft.Activities.UnitTesting;
using System.Collections.Generic;

namespace WFCSTest
{
    [TestClass]
    public class MotherActivityTest
    {
        [TestMethod]
        public void TestMotherActivity1()
        {

            SortedList<IntContainer, SimpleData> input = new SortedList<IntContainer, SimpleData>();
            input.Add(new IntContainer(42), new SimpleData(42, "toto"));
            input.Add(new IntContainer(84), new SimpleData(84, "titi"));

            MotherActivity activity = ActivityCompiler.Instance.GetMotherActivity();
            WorkflowInvokerTest host = WorkflowInvokerTest.Create(activity);
            host.InArguments.IntToAdd = new IntContainer(21);
            host.InArguments.DataToProcess = input;
            try
            {
                host.TestActivity();
                SortedList<IntContainer, SimpleData> res = host.OutArguments.ProcessedData;
                Assert.AreEqual(res.Count, input.Count);
            }
            finally
            {
                host.Tracking.Trace();
            }
        }
    }
}

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using WFCS;
using Microsoft.Activities.UnitTesting;

namespace WFCSTest
{
    [TestClass]
    public class PatriarchActivityTest
    {
        [TestMethod]
        public void TestPatriarchActivity1()
        {
            PatriarchActivity activity = ActivityCompiler.Instance.GetPatriarchActivity();
            WorkflowInvokerTest host = WorkflowInvokerTest.Create(activity);
            //host.InArguments.IntToAdd = new IntContainer(21);
            //host.InArguments.DataToProcess = new SortedList<IntContainer, SimpleData>();
            //host.InArguments.ProcessedData = new SortedList<IntContainer, SimpleData>();
            try
            {
                host.TestActivity();
                SortedList<IntContainer, SimpleData> res = host.OutArguments.ProcessedData;
                Assert.AreEqual(res.Count, 2);
            }
            finally
            {
                host.Tracking.Trace();
            }
        }


    }
}

0 个答案:

没有答案