简体   繁体   English

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

[英]WF 4.5.1 Expression Activity type 'CSharpValue`1' requires compilation in order to run

I'm trying to run an activity but I get this error at run time: 我正在尝试运行一项活动,但在运行时出现此错误:

Expression Activity type 'CSharpValue`1' requires compilation in order to run. 表达式活动类型'CSharpValue`1'需要进行编译才能运行。 Please ensure that the workflow has been compiled. 请确保工作流程已编译。

looking in the unit test output I see: 在单元测试输出中,我看到:

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.

the compilation seems to run ok. 编译似乎运行正常。

I used the code in this page to compile the workflow: http://msdn.microsoft.com/en-us/library/jj591618%28v=vs.110%29.aspx#CodeWorkflows 我使用此页中的代码来编译工作流: http : //msdn.microsoft.com/zh-cn/library/jj591618%28v=vs.110%29.aspx#CodeWorkflows

I have no clue what the problem is, and the message is not helpful as where the error lies imho. 我不知道问题出在什么地方,因为错误所在,恕我直言,该消息没有帮助。 yeah, got it, something hasn't been compiled, then how do I compile it? 是的,知道了,尚未编译某些东西,那我该如何编译呢?

would be very grateful for an explanation. 非常感谢您的解释。

I'm using visual 2013 update 4 with .net 4.5.1 我正在使用带有.net 4.5.1的Visual 2013 Update 4

Here is a small test case which I hope highlights correctly the problem. 这是一个小的测试用例,我希望可以正确地指出问题所在。

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;
        }
    }
}

and the unit tests that coresponds to these three activities: (requires Microsoft..Activities.UnitTesting NuGet package) 以及与这三个活动相对应的单元测试:(需要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();
            }
        }


    }
}

Please follow the below steps to resolve the issue -- 请按照以下步骤解决问题-

Create a class that inherits from WorkflowServiceHostFactory Add ServiceActivation in web.config 创建一个从WorkflowServiceHostFactory继承的类在web.config中添加ServiceActivation

Workflow Services don't have an SVC file, so you can use the 'Configuration Based Activation' feature to activate the services. Workflow Services没有SVC文件,因此您可以使用“基于配置的激活”功能来激活服务。 You would need to edit your web.config to add support for a factory. 您需要编辑web.config来添加对工厂的支持。 In the ServiceHostingEnvironmentSection section, provide the activation details about the service under the tag. 在ServiceHostingEnvironmentSection部分中,在标签下提供有关服务的激活详细信息。

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

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