[WF4] Valider le Result d'une Activity<TResult>
On m’a déjà dit une paire de fois, qu'il était impossible d'ajouter une contrainte ou de valider d'argument Result d'une Activity
Désoler de briser ce mythe, cette opération est possible!
Comme pour toute opération de ce genre, cela passe par la réécriture de la méthode CacheMetadata().
Par exemple pour une activité que j'ai codée récemment (du type sensé être le plus complexe, car héritant de AsyncCodeActivity
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.ComponentModel;
using MyMceSleep.Common;
namespace MyMceSleep.Workflow.Activities
{
public sealed class AskUser : AsyncCodeActivity<enummessageboxresult>
{
[RequiredArgument]
[DefaultValue(0)]
public InArgument<int32> TimeConfigured { get; set; }
/// <summary>
/// BeginExecute Async
/// </summary>
/// <param name="context">
/// <param name="callback">
/// <param name="state">
/// <returns></returns>
protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
{
Func<imessageboxextension enummessageboxresult="" int32,="" ,=""> funct = Ask;
context.UserState = funct;
return funct.BeginInvoke(
context.GetExtension<imessageboxextension>(),
TimeConfigured.Get(context),
callback,
state);
}
/// <summary>
/// EndExecute Async
/// </summary>
/// <param name="context">
/// <param name="result">
/// <returns></returns>
protected override EnumMessageBoxResult EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
{
Func<imessageboxextension enummessageboxresult="" int32,="" ,=""> funct = context.UserState as Func<imessageboxextension enummessageboxresult="" int32,="" ,="">;
return funct.EndInvoke(result);
}
/// <summary>
/// Interroger l'utilisateur
/// </summary>
/// <param name="messageBoxExtension">
/// <param name="timeConfigured">
/// <returns></returns>
private static EnumMessageBoxResult Ask(IMessageBoxExtension messageBoxExtension,Int32 timeConfigured)
{
return messageBoxExtension.Ask(timeConfigured);
}
/// <summary>
/// CacheMetadata
/// </summary>
/// <param name="metadata">
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
if (TimeConfigured == null)
{
metadata.AddValidationError(
new System.Activities.Validation.ValidationError(
"TimeConfigured must be set!",
false,
"TimeConfigured"));
}
else
{
RuntimeArgument arg = new RuntimeArgument("TimeConfigured", typeof(int), ArgumentDirection.In);
metadata.AddArgument(arg);
metadata.Bind(TimeConfigured, arg);
}
if (Result == null)
{
metadata.AddValidationError(
new System.Activities.Validation.ValidationError(
"Result must be set!",
false,
"Result"));
}
else
{
RuntimeArgument arg = new RuntimeArgument("Result", typeof(EnumMessageBoxResult), ArgumentDirection.Out);
metadata.AddArgument(arg);
metadata.Bind(Result, arg);
}
}
}
}
Comme on le voit bien dans la méthode CacheMetadata, je me suis permis de faire un test afin de forcer l'utilisateur à affecter une variable à l'argument Result.
Et bien que mon activité de base soit complexe, cela ne change rien à la validation présente sur Result.
Facile, il suffisait juste d'y penser ;)