L’objectif de ce tutoriel, relatif au troisième cours, est de simuler un appel d’offre.
Il existe trois types d’appels d’offre :
- La consultation restreinte où on fait appel à un fournisseur qui fait une offre. L’offre est validée si son montant est inférieur au budget
- L’appel d’offre normal est évalué soit par la commission des marchés soit par le service d’achats qui peuvent accepter ou rejeter la réponse du fournisseur
- Le méga-projet requiert une validation de la présidence de la république. Si après 15 jours, aucune validation n’est effectuée, l’appel est considéré comme rejeté.
Etape 1 – Création de la solution et des types utilisés
- Lancez VS 2013
- Créez une application console Workflow appelée « Tutoriel31 »
- A partir de l’explorateur de solutions, supprimez « workflow1.xaml »
- Ajoutez une nouvelle activité appelée « AppelOffre.xaml »
- Ouvrez « Program.cs » et effacez le contenu de la méthode « Main »
static void Main(string[] args)
{
}
- Ajoutez au projet une classe publique appelée « AppelOffreData »
- Ajoutez à cette classe une propriété publique appelée « Categorie » de type « String » en lecture et écriture
- Ajoutez à cette classe une propriété publique appelée « Budget » de type « Decimal » en lecture et écriture
- Le listing de la classe devrait être comme suit :
public class AppelOffreData
{
/// <summary>
/// catégorie de l'appel d'offre
/// </summary>
public string Categorie { get; set; }
/// <summary>
/// budget
/// </summary>
public Decimal Budget { get; set; }
}
- Compilez la solution en appuyant sur « F6 » pour vérifier qu’il n’y a pas d’erreurs.
Etape 2 : Création d’une activité d’attente de réponse
L’objectif de cette étape est de créer une activité qui attend une réponse du monde extérieur. On effectue ceci en utilisant les signets. Remarquez que nous allons utiliser « NativeActivity » au lieu de « CodeActivity » car « NativeActivity » permet d’accéder au moteur de workflows.
- Créez une activité de code appelée « AttendreReponse »
- Modifiez la classe « AttendreReponse » en la rendant générique. Ça permettra d’attendre des réponses de n’importe quel type.
- Changez le parent de la classe « AttendreReponse » en mettant « NativeActivity<T> » au lieu de CodeActivity
- Le code devrait être comme suit :
public sealed class AttendreReponse<T> : NativeActivity<T>
{
// Define an activity input argument of type string
public InArgument<string> Text { get; set; }
// If your activity returns a value, derive from CodeActivity<TResult>
// and return the value from the Execute method.
protected override void Execute(CodeActivityContext context)
{
// Obtain the runtime value of the Text input argument
string text = context.GetValue(this.Text);
}
}
- Supprimez la déclaration de l’argument « Text »
- Supprimez le code de la méthode « Execute »
- Ajoutez une propriété publique de type « String » appelée « NomSignet ». Elle servira à donner un nom au signet vu que notre workflow contiendra plusieurs signets.
public string NomSignet { get; set; }
- Ajoutez une autre propriété publique de type « String » et dont le nom est « Destinataire »
public string Destinataire { get; set; }
- Ajoutez une méthode privée appelée SignetCallBack dont le premier parmaètre « context » est de type « NativeActivityContext », le deuxième paramètre « signet » de type « Bookmark » et le troisième paramètre « valeur » de type « object ». Cette méthode est appelée « callback ». Elle est appelée lorsqu’un évènement externe relance le signet.
- Dans le code de cette méthode, si la valeur est différente de null, affectez-là à « Result »
- Le listing de la méthode est comme suit :
private void SignetCallback(NativeActivityContext context, Bookmark bk, object valeur)
{
if (valeur != null)
Result.Set(context, valeur);
}
- Changez le type du paramètre de la méthode « Execute » de « CodeActivityContext » vers « NativeActivityContext »
- Dans la méthode « Execute », affichez en mode console le nom du signet et son destinataire
- Dans la méthode « Execute », créez un signet dont le nom est « NomSignet » et dont le callback pointe sur la méthode « SignetCallback »
- Le listing de la méthode « Execute » devrait être comme ceci :
protected override void Execute(NativeActivityContext context)
{
Console.WriteLine("Création du signet {0} - destinataire : {1}", NomSignet, Destinataire);
context.CreateBookmark(NomSignet, new BookmarkCallback(SignetCallback));
}
- La classe « NativeActivity » a une propriété virtuelle appelée « CanInduceIdle » qui est par défaut à « false ». La classe doit redéfinir cette propriété à « true » pour permettre au workflow d’entrer en mode « idle » (veille).
protected override bool CanInduceIdle
{
get
{
return true;
}
}
- Le listing complet de la classe AttendreReponse et comme ceci :
public sealed class AttendreReponse<T> : NativeActivity<T>
{
public string Destinataire { get; set; }
public string NomSignet { get; set; }
protected override void Execute(NativeActivityContext context)
{
Console.WriteLine("Création du signet {0} - destinataire : {1}", NomSignet, Destinataire);
context.CreateBookmark(NomSignet, new BookmarkCallback(SignetCallback));
}
private void SignetCallback(NativeActivityContext context, Bookmark bk, object valeur)
{
if (valeur != null)
Result.Set(context, valeur);
}
protected override bool CanInduceIdle
{
get
{
return true;
}
}
}
- Compilez en appuyant sur « F6 » pour vérifier qu’il n’y a pas d’erreurs.
Etape 3 : Création de l’offre
L’objectif de cette étape est de créer une méthode qui demande la catégorie et le budget dans le but de créer un appel d’offres.
- A partir de l’explorateur de solution ouvrez le fichier « Program.cs »
- Ajoutez la méthode suivante « GetOffreData » qui lit les informations de l’appel d’offre à partir de la console et LireDecimal quii permet d’entrer un nombre numérique
static decimal LireDecimal(string text)
{
decimal result = 0;
do
{
Console.WriteLine(text);
var succes = decimal.TryParse(Console.ReadLine(), out result);
if (!succes)
Console.WriteLine("veuillez entrer une valeur numérique correcte et positive");
} while (result <= 0);
return result;
}
static AppelOffreData GetOffreData()
{
char c;
do
{
Console.WriteLine("1 - Consultation restreinte");
Console.WriteLine("2 - Norma");
Console.WriteLine("3 - Méga-Projet");
c = Console.ReadKey().KeyChar;
} while ((c != '1') && (c != '2') && (c != '3'));
string categorie = null;
switch (c)
{
case '1': categorie = "Consultation";
break;
case '2': categorie = "Normal";
break;
case '3': categorie = "Méga";
break;
}
decimal result = LireDecimal("Budget :");
return new AppelOffreData()
{
Categorie = categorie,
Budget = result
};
}
- Compilez en appuyant sur « F6 » pour vérifier qu’il n’y a pas d’erreurs.
La suite du tutoriel :