C# kifejezések

A .NET-keretrendszer 4.5-től kezdve a C#-kifejezések támogatottak a Windows Workflow Foundationben (WF). A Visual Studio 2012-ben létrehozott új C# munkafolyamat-projektek, amelyek a .NET-keretrendszer 4.5-ös verziót célozzák, C# kifejezéseket használnak, a Visual Basic munkafolyamat-projektek pedig Visual Basic-kifejezéseket használnak. A Visual Basic kifejezéseket használó meglévő .NET Framework 4 munkafolyamat-projektek a projekt nyelvétől függetlenül áttelepíthetők a .NET-keretrendszer 4.6.1-be, és támogatottak. Ez a témakör áttekintést nyújt a WF-ben található C#-kifejezésekről.

C#-kifejezések használata munkafolyamatokban

C#-kifejezések használata a Munkafolyamat-tervezőben

A .NET-keretrendszer 4.5-től kezdve a C#-kifejezések támogatottak a Windows Workflow Foundationben (WF). A Visual Studio 2012-ben létrehozott, .NET-keretrendszer 4.5-ös célként megadott C# munkafolyamat-projektek C# kifejezéseket használnak, míg a Visual Basic munkafolyamat-projektek Visual Basic-kifejezéseket használnak. A kívánt C# kifejezés megadásához írja be az Enter a C# kifejezés címkével ellátott mezőbe. Ez a címke akkor jelenik meg a tulajdonságok ablakában, ha a tevékenység ki van jelölve a tervezőben vagy a munkafolyamat-tervező tevékenységében. Az alábbi példában két WriteLine tevékenység található egy Sequence-ben, ami egy NoPersistScope-ben van.

Automatikusan létrehozott sorozattevékenységet bemutató képernyőkép.

Megjegyzés:

A C#-kifejezések csak a Visual Studióban támogatottak, és nem támogatottak az újra üzemeltetett munkafolyamat-tervezőben. Az újra üzemeltetett tervezőben támogatott új WF45-funkciókkal kapcsolatos további információkért tekintse meg az Új munkafolyamat-alaprendszer 4.5 funkcióinak támogatása az áthelyezett munkafolyamat-tervezőben című témakört.

Visszamenőleges kompatibilitás

A .NET-keretrendszer 4 C# munkafolyamat-projektjeiben, amelyeket a .NET-keretrendszer 4.6.1-be migráltak, támogatottak a Visual Basic-kifejezések. Amikor a munkafolyamat-tervezőben megtekintjük a Visual Basic kifejezéseket, akkor a meglévő Visual Basic kifejezés szövegét lecserélik arra a kifejezésre, hogy "Az értéket XAML-ben állították be", kivéve, ha a Visual Basic kifejezés érvényes C# szintaxisú. Ha a Visual Basic kifejezés érvényes C# szintaxis, akkor a kifejezés megjelenik. A Visual Basic-kifejezések C#-ra való frissítéséhez szerkesztheti őket a munkafolyamat-tervezőben, és megadhatja a megfelelő C# kifejezést. A Visual Basic-kifejezéseket nem szükséges C#-ra frissíteni, de miután a kifejezéseket frissítette a munkafolyamat-tervezőben, a rendszer C#-ra konvertálja őket, és nem lesz visszaállítva Visual Basicre.

C#-kifejezések használata kód-munkafolyamatokban

A C# kifejezések támogatottak a .NET-keretrendszer 4.6.1 kódalapú munkafolyamataiban, de a munkafolyamat meghívása előtt a C#-kifejezéseket a következővel TextExpressionCompiler.Compilekell lefordítani: . A munkafolyamat-szerzők a CSharpValue egy kifejezés r-értékének és a CSharpReference egy kifejezés l-értékének ábrázolására használhatják. Az alábbi példában egy munkafolyamat jön létre egy Assign tevékenységgel és egy WriteLine tevékenységgel, amelyek egy Sequence tevékenységben találhatók. A CSharpReference paraméter a To kifejezés argumentumához Assignvan megadva, és a kifejezés l-értékét jelöli. Az CSharpValue a Value argumentumhoz és a Assign argumentumhoz van megadva a Text esetében, és a két kifejezés r-értékét jelöli.

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

A munkafolyamat létrehozása után a C#-kifejezések fordítása a CompileExpressions segédmetódus meghívásával történik, majd meghívja a munkafolyamatot. A következő példa a CompileExpressions metódus.

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

Megjegyzés:

Ha a C#-kifejezések nincsenek lefordítva, NotSupportedException a rendszer a következőhöz hasonló üzenettel hívja meg a munkafolyamatot: Expression Activity type 'CSharpValueaz 1'-nek fordításra van szüksége a futtatáshoz. Győződjön meg arról, hogy a munkafolyamat összeállítása megtörtént.

Ha az egyéni kódalapú munkafolyamatot használja DynamicActivity, akkor a CompileExpressions metódus bizonyos módosításaira van szükség az alábbi kód példában bemutatott módon.

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

A C#-kifejezéseket dinamikus tevékenységben fordító túlterhelésben számos különbség van CompileExpressions .

  • A paraméter egy CompileExpressionsDynamicActivity.

  • A típusnevet és a névteret a rendszer a DynamicActivity.Name tulajdonság használatával kéri le.

  • TextExpressionCompilerSettings.ForImplementation trueértékre van állítva.

  • A CompiledExpressionInvoker.SetCompiledExpressionRootForImplementation van meghívva a CompiledExpressionInvoker.SetCompiledExpressionRoot helyett.

A kódban lévő kifejezések használatáról további információt a munkafolyamatok, tevékenységek és kifejezések készítése imperatív kóddal című témakörben talál.

C#-kifejezések használata XAML-munkafolyamatokban

A C#-kifejezések támogatottak az XAML-munkafolyamatokban. A lefordított XAML-munkafolyamatok egy típusba vannak lefordítva, a laza XAML-munkafolyamatokat pedig a futtatókörnyezet tölti be, és a munkafolyamat végrehajtásakor egy tevékenységfára fordítja.

Lefordított Xaml

A C#-kifejezések támogatottak olyan lefordított XAML-munkafolyamatokban, amelyek egy .NET-keretrendszer 4.6.1-es verziójára vonatkozó C# munkafolyamat-projekt részeként egy típusra vannak lefordítva. A lefordított XAML az alapértelmezett munkafolyamat-létrehozási típus a Visual Studióban, a .NET Framework 4.6.1-et megcélzó Visual Studióban létrehozott C# munkafolyamat-projektek pedig C# kifejezéseket használnak.

Rugalmas Xaml

A C#-kifejezések laza XAML-munkafolyamatokban támogatottak. A laza XAML-munkafolyamatot betöltő és meghívó munkafolyamat-gazdagépprogramnak meg kell céloznia a .NET-keretrendszer 4.6.1-et, és CompileExpressions be kell állítania true (az alapértelmezett érték false). A CompileExpressions beállításához true hozzon létre egy ActivityXamlServicesSettings példányt, amelynek CompileExpressions tulajdonsága true, és adja meg azt paraméterként a ActivityXamlServices.Load-nek. Ha CompileExpressions nincs beállítva true, egy NotSupportedException következik a következőhöz hasonló üzenettel: Expression Activity type 'CSharpValueA '1' futtatásához fordításra van szükség. Győződjön meg arról, hogy a munkafolyamat összeállítása megtörtént.

ActivityXamlServicesSettings settings = new ActivityXamlServicesSettings
{
    CompileExpressions = true
};

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

Az XAML-munkafolyamatok használatával kapcsolatos további információkért lásd: Munkafolyamatok és tevékenységek szerializálása az XAML-be és onnan.

C#-kifejezések használata az XAMLX munkafolyamat-szolgáltatásokban

A C#-kifejezések támogatottak az XAMLX munkafolyamat-szolgáltatásokban. Ha egy munkafolyamat-szolgáltatást IIS-ben vagy WAS-ban üzemeltetnek, akkor nincs szükség további lépésekre, de ha az XAML munkafolyamat-szolgáltatás saját üzemeltetésű, akkor a C#-kifejezéseket le kell fordítani. Ha egy saját hosztolt XAMLX munkafolyamat-szolgáltatásban szeretné lefordítani a C# kifejezéseket, először töltse be az XAMLX-fájlt egy WorkflowService-be, majd adja át a Body-del a WorkflowService-t a korábbi, a "C#-kifejezések használata a kód munkafolyamatokban" szakaszban leírt CompileExpressions metódusnak. Az alábbi példában egy XAMLX munkafolyamat-szolgáltatás van betöltve, a C#-kifejezések le lesznek fordítva, majd megnyílik a munkafolyamat-szolgáltatás, és várja a kéréseket.

// 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();

Ha a C#-kifejezések nincsenek lefordítva, a Open művelet sikeres lesz, de a munkafolyamat sikertelen lesz a meghíváskor. A következő CompileExpressions metódus ugyanaz, mint az előző C#-kifejezések használata a kód-munkafolyamatokban szakaszból .

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