XAMLX Workflow with c# expressions

拈花ヽ惹草 提交于 2019-12-11 01:47:07

问题


I'm developing a self host workflow in vs2012/.Net 4.5/WF 4.5 and having quite a hard time figuring out the following message

Expression Activity type 'CSharpValue`1' requires compilation in order to run. Please ensure that the workflow has been compiled.

This error happens when i call a activity generated by a service reference (When you add a WCF service reference, each action on the endpoint become a activity).

Looking around in MSDN i've came across these articles:

  • http://msdn.microsoft.com/en-us/library/ee358749.aspx
  • http://msdn.microsoft.com/en-us/library/29110be7-f4e3-407e-8dbe-78102eb21115#CodeWorkflows

They said that

When a workflow service is hosted in IIS or WAS then no additional steps are required, but if the XAML workflow service is self-hosted, then the C# expressions must be compiled

So, i finally get to my question: What should I do so i can hit F5 and debug my workflow, having it run on IIS? and stop this god damn exception...

I've tried to go to the project config and set to use local IIS as follow:

but since i still get the error i assume it's not working...


回答1:


Old question, but after a day of piecing together various bits of information, I thought I'd share just in case someone else runs into this.

From the C# expressions MSDN documentation:

C# expressions are supported in XAMLX workflow services. When a workflow service is hosted in IIS or WAS then no additional steps are required, but if the XAML workflow service is self-hosted, then the C# expressions must be compiled.

This is true until you add a custom WorkflowHostFactory. In that case, if you override the wrong method, your C# will NOT be compiled. The following code does NOT compile C# expressions and you will get the dreaded:

Expression Activity type 'CSharpValue`1' requires compilation in order to run. Please ensure that the workflow has been compiled.

Or, if you're not looking at tracing messages, the even more helpful:

System.ServiceModel.FaultException: The operation could not be performed because WorkflowInstance '5cfc33d1-b546-4ba8-a8ec-86d3cb16a68b' was aborted.

   public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
    {
        return base.CreateServiceHost(constructorString, baseAddresses);
    }

You can fix this by overriding the other factory method and then compiling your activity using the code provided via MSDN C# Expressions in Workflow Foundation 4.5:

 protected override WorkflowServiceHost CreateWorkflowServiceHost(WorkflowService service, Uri[] baseAddresses)
    {
        CompileExpressions(service.Body);
        return base.CreateWorkflowServiceHost(service, baseAddresses);
    }

Here is the whole WorkflowServiceHostFactory:

 public class MyWorkflowServiceHostFactory : WorkflowServiceHostFactory
{
    protected override WorkflowServiceHost CreateWorkflowServiceHost(WorkflowService service, Uri[] baseAddresses)
    {
        CompileExpressions(service.Body);
        return base.CreateWorkflowServiceHost(service, baseAddresses);
    }

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



回答2:


Despite what the article said about running on IIS/WAS I only managed to run the workflow when I implemented the fabric sugested... this is not an answer for the question... its more like a workaround...



来源:https://stackoverflow.com/questions/13753276/xamlx-workflow-with-c-sharp-expressions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!