Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
À compter de .NET Framework 4.5, les expressions C# sont prises en charge dans Windows Workflow Foundation (WF). Nouveaux projets de flux de travail C# créés dans Visual Studio 2012 qui ciblent .NET Framework 4.5 utilisent des expressions C# et les projets de flux de travail Visual Basic utilisent des expressions Visual Basic. Les projets de flux de travail .NET Framework 4 existants qui utilisent des expressions Visual Basic peuvent être migrés vers .NET Framework 4.6.1, quel que soit le langage du projet et pris en charge. Cette rubrique fournit une vue d’ensemble des expressions C# dans WF.
Utilisation d’expressions C# dans les flux de travail
Utilisation d’expressions C# dans le Concepteur de flux de travail
Utilisation d’expressions C# dans les flux de travail de code
Utilisation d’expressions C# dans les services de flux de travail XAMLX
Utilisation d’expressions C# dans le Concepteur de flux de travail
À compter de .NET Framework 4.5, les expressions C# sont prises en charge dans Windows Workflow Foundation (WF). Les projets de flux de travail C# créés dans Visual Studio 2012 qui ciblent .NET Framework 4.5 utilisent des expressions C#, tandis que les projets de flux de travail Visual Basic utilisent des expressions Visual Basic. Pour spécifier l’expression C# souhaitée, tapez-la dans la zone intitulée Entrée d’une expression C#. Cette étiquette s’affiche dans la fenêtre des propriétés lorsque l’activité est sélectionnée dans le concepteur ou sur l’activité dans le concepteur de flux de travail. Dans l'exemple suivant, deux activités WriteLine sont contenues dans Sequence à l'intérieur de NoPersistScope.
Remarque
Les expressions C# sont prises en charge uniquement dans Visual Studio et ne sont pas prises en charge dans le concepteur de flux de travail réhébergé. Pour plus d’informations sur les nouvelles fonctionnalités WF45 prises en charge dans le concepteur réhébergé, consultez Support for New Workflow Foundation 4.5 Features in the Rehosted Workflow Designer.
Rétrocompatibilité
Les expressions Visual Basic dans les projets de flux de travail .NET Framework 4 C# existants qui ont été migrés vers .NET Framework 4.6.1 sont prises en charge. Lorsque les expressions Visual Basic sont consultées dans le concepteur de flux de travail, le texte de l’expression Visual Basic existante est remplacé par La valeur a été défini en XAML, sauf si l’expression Visual Basic est une syntaxe C# valide. Si l’expression Visual Basic est une syntaxe C# valide, l’expression s’affiche. Pour mettre à jour les expressions Visual Basic en C#, vous pouvez les modifier dans le concepteur de flux de travail et spécifier l’expression C# équivalente. Il n’est pas nécessaire de mettre à jour les expressions Visual Basic en C#, mais une fois que les expressions sont mises à jour dans le concepteur de flux de travail, elles sont converties en C# et peuvent ne pas être rétablies en Visual Basic.
Utilisation d’expressions C# dans les flux de travail de code
Les expressions C# sont prises en charge dans les flux de travail basés sur du code .NET Framework 4.6.1, mais avant que le flux de travail ne puisse être appelé, les expressions C# doivent être compilées à l’aide TextExpressionCompiler.Compilede . Les auteurs de flux de travail peuvent utiliser CSharpValue pour représenter la valeur r d’une expression et CSharpReference représenter la valeur l d’une expression. Dans l’exemple suivant, un flux de travail est créé avec une Assign activité et une WriteLine activité contenue dans une Sequence activité. A CSharpReference est spécifié pour l’argument To du Assign, et représente la valeur l de l’expression. A CSharpValue est spécifié pour l’argument Value du Assign, et pour l’argument Text du WriteLine, et représente la valeur r pour ces deux expressions.
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);
Une fois le flux de travail construit, les expressions C# sont compilées en appelant la CompileExpressions méthode d’assistance, puis le flux de travail est appelé. L’exemple suivant est la CompileExpressions méthode.
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);
}
Remarque
Si les expressions C# ne sont pas compilées, une exception NotSupportedException est levée quand le workflow est appelé, avec un message similaire à celui-ci : Expression Activity type 'CSharpValue1’ doit être compilé pour pouvoir s’exécuter. Assurez-vous que le flux de travail a été compilé. »
Si votre workflow personnalisé basé sur du code utilise DynamicActivity, certaines modifications apportées à la CompileExpressions méthode sont requises, comme illustré dans l’exemple de code suivant.
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);
}
Il existe plusieurs différences dans la surcharge de CompileExpressions qui compile les expressions C# dans une activité dynamique.
Le paramètre pour
CompileExpressionsest unDynamicActivity.Le nom de type et l’espace de noms sont récupérés à l’aide de la
DynamicActivity.Namepropriété.TextExpressionCompilerSettings.ForImplementationest défini surtrue.CompiledExpressionInvoker.SetCompiledExpressionRootForImplementationest appelé au lieu deCompiledExpressionInvoker.SetCompiledExpressionRoot.
Pour plus d’informations sur l’utilisation d’expressions dans le code, consultez Création de flux de travail, d’activités et d’expressions à l’aide du code impératif.
Utilisation d’expressions C# dans des flux de travail XAML
Les expressions C# sont prises en charge dans les flux de travail XAML. Les flux de travail XAML compilés sont compilés en un type, et les flux de travail XAML libres sont chargés par le runtime et compilés dans une arborescence d’activités lorsque le flux de travail est exécuté.
XAML compilé
Les expressions C# sont prises en charge dans les flux de travail XAML compilés qui sont compilés sur un type dans le cadre d’un projet de flux de travail C# qui cible .NET Framework 4.6.1. Le code XAML compilé est le type par défaut de création de flux de travail dans Visual Studio et les projets de flux de travail C# créés dans Visual Studio qui ciblent .NET Framework 4.6.1 utilisent des expressions C#.
XAML libre
Les expressions C# sont prises en charge dans les flux de travail XAML libres. Le programme hôte de flux de travail qui charge et appelle le flux de travail XAML libre doit cibler .NET Framework 4.6.1 et CompileExpressions doit être défini sur true (la valeur par défaut est false). Pour définir CompileExpressions à true, créez une instance ActivityXamlServicesSettings avec sa propriété CompileExpressions définie sur true, puis transmettez-la en tant que paramètre à ActivityXamlServices.Load. Si CompileExpressions n’est pas défini sur true, une exception NotSupportedException est levée avec un message similaire à celui-ci : Expression Activity type 'CSharpValue1’ doit être compilé pour pouvoir s’exécuter. Assurez-vous que le flux de travail a été compilé. »
ActivityXamlServicesSettings settings = new ActivityXamlServicesSettings
{
CompileExpressions = true
};
DynamicActivity<int> wf = ActivityXamlServices.Load(new StringReader(serializedAB), settings) as DynamicActivity<int>;
Pour plus d’informations sur l’utilisation des flux de travail XAML, consultez Sérialisation des flux de travail et des activités vers et depuis XAML.
Utilisation d’expressions C# dans les services de flux de travail XAMLX
Les expressions C# sont prises en charge dans les services de flux de travail XAMLX. Lorsqu’un service de flux de travail est hébergé dans IIS ou WAS, aucune étape supplémentaire n’est requise, mais si le service de flux de travail XAML est auto-hébergé, les expressions C# doivent être compilées. Pour compiler les expressions C# dans un service de flux de travail XAMLX auto-hébergé, chargez d’abord le fichier XAMLX dans un WorkflowService, puis passez le Body de la WorkflowService à la méthode CompileExpressions décrite dans la section précédente Utilisation des expressions C# dans les flux de travail de code. Dans l’exemple suivant, un service de flux de travail XAMLX est chargé, les expressions C# sont compilées, puis le service de flux de travail est ouvert et attend les demandes.
// 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();
Si les expressions C# ne sont pas compilées, l’opération Open réussit, mais le flux de travail échoue lorsqu’il est appelé. La méthode suivante CompileExpressions est la même que la méthode de l’utilisation des expressions C# précédentes dans la section flux de travail de code .
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);
}