Manipuler des arguments n’a rien de bien ardu en soit mais dans certain cas, on peut se retrouver avec des manipulations qui donnent des comportements incompréhensibles. Le coupable se retrouve bien souvent sur la manière de vérifier si un argument a été saisie.

La méthode semblera la plus évidente est la validation de l’activité lors du design du workflow. On ajoute une contrainte sur l’argument et par la suite et le designer devra obligatoirement saisir un argument.

Voici 2 de mes précédents articles sur le sujet :

[WF4] Ajouter des contraintes à une activité (1/2)

[WF4] Ajouter des contraintes à une activité (2/2)

On peut aussi envisager l’utilsiation de l’attribut [RequiredArgument] sur l’argument obligatoire.

 

Dans un scénario où notre argument serrait optionel, ces approches ne sont pas possibles. Il nous faut alors faire attention à l’état des arguments avant de les récupérer.

Voici un petit exemple d’activité :

public class User
{
    public Int32 Id { get; set; }
    public String Name { get; set; }
}

public sealed class MyCodeActivity : CodeActivity
{
    public InArgument<User> User { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
    }
}

Au moment de l’exécution de l’activité, si on souhaite accéder à l’argument User, il faudra être prudent. Un code tel que celui-ci lèvera une exception si l’argument n’a pas été défini dans le workflow :

// Pas bien
String userName = context.GetValue(this.User).Name;

Des codes tels que les suivant seront bien évidemment plus propres ;)

// Bien
User user = context.GetValue(this.User);

// Aussi bien
User user = this.User.Get(context);

Mais après quelques test sur mes activités et celles d’autres développeurs je suis arrivé sur des cas où pour tester l’argument, les développeurs utilisaient un code tel que celui-ci :

Boolean test = this.User.Expression != null; // pas bon si User est null!!!!

Car le test suivant ne leur permettait pas de connaitre l’état de l’argument:

Boolean test = this.User != null;

Etrange ?

Non, pas tant que cela. On pense toujours que votre activité va passer un jour ou l’autre pas le designer de WF4, qu’il a des défauts… etc…

Mais il ne faut pas l’incriminer systématiquement car dans le cas présent, ce n’est pas vraiment lui qui pose souci, mais le développeur qui n’a pas penser à lui donner un petit coup de pousse ;) en lui donnanr une valeur par défaut à notre argument.

L’attribut [DefaultValue(null)] est une très bonne solution dans le cas présent et pourrait constituer un élément à inclure dans vos bonnes pratiques pour WF4.

Doù le code complet suivant:

public sealed class MyCodeActivity : CodeActivity
{
    [DefaultValue(null)]
    public InArgument<User> User { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
        Boolean test = this.User != null;
    }
}

En plus, via ce type de code on test l’argument avant même de se préparer à utiliser la moindre ressources du contexte. D’où un probable gain de performance à l’exécution.