Sdílet prostřednictvím


Výrazy 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 WriteLine jsou dvě aktivity obsaženy uvnitř Sequence uvnitř .NoPersistScope

Screenshot that shows an automatically created sequence activity.

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 návrháři pro opětovné hostování naleznete v tématu Podpora nových funkcí Pracovních postupů Foundation 4.5 v Návrháři pracovních postupů v novém hostování.

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 existujícího výrazu Jazyka Visual Basic je nahrazen hodnotou byl nastaven v jazyce XAML, pokud výraz jazyka Visual Basic není platná syntaxe jazyka 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 A CSharpValue je určena pro Value argument , Assigna pro Text argument WriteLine, a představuje hodnotu r 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);
}

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

  • Parametrem je DynamicActivity.CompileExpressions

  • Název typu a obor názvů se načtou pomocí DynamicActivity.Name vlastnosti.

  • TextExpressionCompilerSettings.ForImplementation je nastavena na truehodnotu .

  • 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 true, vytvořte ActivityXamlServicesSettings instanci s vlastností CompileExpressions nastavenou na truea předejte ji jako parametr .ActivityXamlServices.Load Pokud CompileExpressions není nastavena na truehodnotu , NotSupportedException vyvolá se zpráva podobná následující: Expression Activity type 'CSharpValue1' vyžaduje kompilaci, aby bylo možné spustit. 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 WorkflowServicea pak předejte WorkflowService Body metodu CompileExpressions popsanou v předchozí části Použití výrazů jazyka C# v části pracovních postupů 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);
}