Sdílet prostřednictvím


Výrazy jazyka C#

Počínaje rozhraním .NET Framework 4.5 se ve Windows Workflow Foundation (WF) podporují výrazy jazyka C#. Nové projekty pracovních postupů jazyka C# vytvořené v sadě Visual Studio 2012, které cílí na rozhraní .NET Framework 4.5, používají výrazy jazyka C# a projekty pracovních postupů jazyka Visual Basic používají výrazy jazyka Visual Basic. Existující projekty pracovních postupů rozhraní .NET Framework 4, které používají výrazy jazyka Visual Basic, lze migrovat na rozhraní .NET Framework 4.6.1 bez ohledu na jazyk projektu a jsou podporovány. Toto téma obsahuje přehled výrazů jazyka C# ve WF.

Použití výrazů jazyka C# v pracovních postupech

Použití výrazů jazyka C# v Návrháři pracovního postupu

Počínaje rozhraním .NET Framework 4.5 se ve Windows Workflow Foundation (WF) podporují výrazy jazyka C#. Projekty pracovních postupů jazyka C# vytvořené v sadě Visual Studio 2012, které cílí na rozhraní .NET Framework 4.5, používají výrazy jazyka C#, zatímco projekty pracovních postupů jazyka Visual Basic používají výrazy jazyka Visual Basic. Pokud chcete zadat požadovaný výraz jazyka C#, zadejte ho do pole s popiskem Enter a C# expression. Tento popisek se zobrazí v okně vlastností, když je aktivita vybrána v návrháři nebo u aktivity v návrháři pracovního postupu. V následujícím příkladu jsou dvě WriteLine aktivity obsaženy uvnitř Sequence, které jsou v NoPersistScope.

Snímek obrazovky znázorňující automaticky vytvořenou sekvenční aktivitu

Poznámka:

Výrazy jazyka C# jsou podporovány pouze v sadě Visual Studio a nejsou podporovány v návrháři pracovních postupů v znovu hostované verzi. Další informace o nových funkcích WF45 podporovaných v přehostovaném návrháři naleznete v článku Podpora nových funkcí Pracovních postupů Foundation 4.5 v přehostovaném Návrháři pracovních postupů.

Zpětná kompatibilita

Výrazy jazyka Visual Basic v existujících projektech pracovních postupů .NET Framework 4 C#, které byly migrovány do rozhraní .NET Framework 4.6.1, jsou podporovány. Pokud jsou výrazy jazyka Visual Basic zobrazeny v návrháři pracovního postupu, text stávajícího výrazu v jazyce Visual Basic je nahrazen hodnota byla nastavena v XAML, pokud výraz jazyka Visual Basic není platná syntaxe v jazyce C#. Pokud je výraz jazyka Visual Basic platná syntaxe jazyka C#, zobrazí se výraz. Pokud chcete aktualizovat výrazy jazyka Visual Basic na jazyk C#, můžete je upravit v návrháři pracovního postupu a zadat ekvivalentní výraz jazyka C#. Není nutné aktualizovat výrazy jazyka Visual Basic na jazyk C#, ale jakmile se výrazy aktualizují v návrháři pracovního postupu, převedou se na jazyk C# a nemusí se vrátit k jazyku Visual Basic.

Použití výrazů jazyka C# v pracovních postupech kódu

Výrazy jazyka C# jsou podporovány v pracovních postupech založených na kódu rozhraní .NET Framework 4.6.1, ale před vyvolání pracovního postupu je nutné výrazy jazyka C# zkompilovat pomocí TextExpressionCompiler.Compile. Autoři pracovního postupu můžou použít CSharpValue k reprezentaci r-hodnoty výrazu a CSharpReference k reprezentaci l-hodnoty výrazu. V následujícím příkladu se vytvoří pracovní postup s aktivitou Assign a aktivitou obsaženou WriteLine v aktivitě Sequence . Hodnota A CSharpReference je určena pro To argument Assign, a představuje l-hodnotu výrazu. Hodnota CSharpValue je určena pro argument Value funkce Assign a pro argument Text funkce WriteLine a představuje r-hodnotu pro tyto dva výrazy.

Variable<int> n = new Variable<int>
{
    Name = "n"
};

Activity wf = new Sequence
{
    Variables = { n },
    Activities =
    {
        new Assign<int>
        {
            To = new CSharpReference<int>("n"),
            Value = new CSharpValue<int>("new Random().Next(1, 101)")
        },
        new WriteLine
        {
            Text = new CSharpValue<string>("\"The number is \" + n")
        }
    }
};

CompileExpressions(wf);

WorkflowInvoker.Invoke(wf);

Po vytvoření pracovního postupu se výrazy jazyka C# kompilují voláním CompileExpressions pomocné metody a pak se pracovní postup vyvolá. Následující příklad je CompileExpressions metoda.

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

Poznámka:

Pokud výrazy jazyka C# nejsou kompilovány, NotSupportedException vyvolá se při vyvolání pracovního postupu se zprávou podobnou následující: Expression Activity type 'CSharpValue1 vyžaduje kompilaci, aby bylo možné spustit. Ujistěte se, že byl pracovní postup zkompilován.

Pokud váš vlastní pracovní postup založený na kódu používá DynamicActivity, pak jsou vyžadovány některé změny CompileExpressions metody, jak je znázorněno v následujícím příkladu kódu.

static void CompileExpressions(DynamicActivity dynamicActivity)
{
    // activityName is the Namespace.Type of the activity that contains the
    // C# expressions. For Dynamic Activities this can be retrieved using the
    // name property , which must be in the form Namespace.Type.
    string activityName = dynamicActivity.Name;

    // 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 = dynamicActivity,
        Language = "C#",
        ActivityName = activityType,
        ActivityNamespace = activityNamespace,
        RootNamespace = null,
        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.");
    }

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

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

Existuje několik rozdílů v přetížení CompileExpressions, které kompilují výrazy v jazyce C# v dynamické aktivitě.

  • Parametrem pro CompileExpressions je DynamicActivity.

  • Název typu a obor názvů se získají pomocí vlastnosti DynamicActivity.Name.

  • TextExpressionCompilerSettings.ForImplementation je nastaveno na true.

  • CompiledExpressionInvoker.SetCompiledExpressionRootForImplementation je volána místo CompiledExpressionInvoker.SetCompiledExpressionRoot.

Další informace o práci s výrazy v kódu naleznete v tématu Vytváření pracovních postupů, aktivit a výrazů pomocí imperativního kódu.

Použití výrazů jazyka C# v pracovních postupech XAML

Výrazy jazyka C# jsou podporovány v pracovních postupech XAML. Kompilované pracovní postupy XAML jsou kompilovány do typu a volné pracovní postupy XAML se načítají modulem runtime a kompilují se do stromu aktivit při spuštění pracovního postupu.

Zkompilovaný xaml

Výrazy jazyka C# jsou podporovány v kompilovaných pracovních postupech XAML, které jsou kompilovány na typ jako součást projektu pracovního postupu jazyka C#, který cílí na rozhraní .NET Framework 4.6.1. Kompilovaný XAML je výchozí typ vytváření pracovních postupů v sadě Visual Studio a projekty pracovních postupů jazyka C# vytvořené v sadě Visual Studio, které cílí na rozhraní .NET Framework 4.6.1, používají výrazy jazyka C#.

Volný xaml

Výrazy jazyka C# jsou podporovány ve volných pracovních postupech XAML. Hostitelský program pracovního postupu, který načte a vyvolá uvolněný pracovní postup XAML, musí cílit na rozhraní .NET Framework 4.6.1 a CompileExpressions musí být nastaven na true (výchozí hodnota je false). Chcete-li nastavit CompileExpressions na true, vytvořte instanci ActivityXamlServicesSettings s vlastností CompileExpressions nastavenou na true a předejte ji jako parametr do ActivityXamlServices.Load. Pokud CompileExpressions není nastavena na true, bude vyvolána NotSupportedException se zprávou podobnou následující: Expression Activity type 'CSharpValue1' vyžaduje kompilaci k tomu, aby mohl být spuštěn. Ujistěte se, že byl pracovní postup zkompilován.

ActivityXamlServicesSettings settings = new ActivityXamlServicesSettings
{
    CompileExpressions = true
};

DynamicActivity<int> wf = ActivityXamlServices.Load(new StringReader(serializedAB), settings) as DynamicActivity<int>;

Další informace o práci s pracovními postupy XAML naleznete v tématu Serializace pracovních postupů a aktivit do a z XAML.

Použití výrazů jazyka C# ve službách pracovních postupů XAMLX

Výrazy jazyka C# jsou podporovány ve službách pracovních postupů XAMLX. Pokud je služba pracovního postupu hostovaná ve službě IIS nebo WAS, není nutné provádět žádné další kroky, ale pokud je služba pracovního postupu XAML hostovaná samostatně, je nutné zkompilovat výrazy jazyka C#. Chcete-li zkompilovat výrazy jazyka C# ve službě pracovního postupu XAMLX v místním prostředí, nejprve načtěte soubor XAMLX do WorkflowService, a pak předejte Body z WorkflowService metodě CompileExpressions, jak je popsáno v předchozí části Použití výrazů jazyka C# v pracovních postupech kódu. V následujícím příkladu se načte služba pracovního postupu XAMLX, zkompilují se výrazy jazyka C# a pak se služba pracovního postupu otevře a čeká na požadavky.

// Load the XAMLX workflow service.
WorkflowService workflow1 =
    (WorkflowService)XamlServices.Load(xamlxPath);

// Compile the C# expressions in the workflow by passing the Body to CompileExpressions.
CompileExpressions(workflow1.Body);

// Initialize the WorkflowServiceHost.
var host = new WorkflowServiceHost(workflow1, new Uri("http://localhost:8293/Service1.xamlx"));

// Enable Metadata publishing/
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);

// Open the WorkflowServiceHost and wait for requests.
host.Open();
Console.WriteLine("Press enter to quit");
Console.ReadLine();

Pokud výrazy jazyka C# nejsou kompilovány, operace bude úspěšná, Open ale pracovní postup při vyvolání selže. Následující CompileExpressions metoda je stejná jako metoda z předchozí použití výrazů jazyka C# v části pracovní postupy kódu .

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