7
votes

FluenteValidation, cycle de vie des validateurs et en utilisant des validateurs à vérifier contre dB

J'utilise fluentvalidation dans mon projet mvc4 . Tout ce qui est fonctionne parfaitement et il est connecté à mon ioc ( Structuremap ).

j'ai 2 questions:

  1. Comment dois-je gérer cycle de vie de mes validateurs ? Est-ce que ça va de leur faire singleton ? ou cela ne fait aucune différence et je peux gérer le cycle de vie selon mes besoins ? Quelle est la meilleure pratique ici?

  2. fluentvalidation est très bon. Je l'utilise pour Validations simples (comme: la propriété n'est pas vide, etc.). Je pense à faire des validations dB en l'utilisant (comme: La valeur de la propriété est unique .) Je peux transmettre mon référentiel à celui-ci en utilisant < Strong> Structuremap et vérifiez les valeurs contre la DB. est-ce une bonne idée ? Ou devrais-je mettre en œuvre cette logique dans ma couche de service et non dans mon ivenidator?

    Si vous l'avez utilisé dans des scénarios similaires, quelle était votre expérience?


0 commentaires

3 Réponses :


2
votes

La validation est sans surprise un complexe et dépend généralement de l'architecture de votre application, mais voici mes pensées.

  1. Les validateurs doivent être gérés en fonction de vos besoins. Je quitterais généralement des instances de classe statiques de servir généralement des problèmes d'infrastructure telles que des usines ou des constructeurs d'objets.

  2. Sans aucun doute, la bibliothèque fluentevalidation est excellente. Les problèmes typiques rencontrés par la validation ne résultent pas de la bibliothèque que vous choisissez, mais la manière dont la validation est appliquée. Dans la plupart des applications typiques La validation d'un objet / entité / domaine est contextuelle, la validation dépend entièrement du contexte de l'opération que vous essayez d'effectuer. Par exemple, la validation sur le même objet est probablement différente pour la persistance, la modification d'un attribut, de l'état changeant, de l'ETL, etc. Conservez tout cela à l'esprit, je pense que la validation appartient aussi près que possible de l'opération effectuée.

    Espérons que cela aide.


1 commentaires

Merci beaucoup @kane. Très utile. :)



5
votes

J'ai utilisé la flueuretvalidation depuis des années et j'ai demandé et avons compris vos questions.

  1. Personnellement, le coût de la création d'un validateur n'est pas très cher, alors je ne les fais pas singletons. J'ai rencontré des problèmes avec des singletons nécessitant un accès au httpContext pour exiger un téléchargement de fichier. Ce qui se passe, c'est le premier httpcontext est toujours utilisé dans la validation plutôt que l'actuel.

    je vous recommande personnellement que vous n'utilisez pas singletons .

    1. Je le fais en fait tout le temps et je l'aime. Soyez juste attentif que toute dépendance que vous injectez soit efficace. Si votre requête de base de données effectue une numérisation de table complète et prend 30 secondes, ce n'est pas une bonne expérience. Comme je l'ai dit ci-dessus, j'injecte habituellement httpContext pour vérifier si les fichiers ont été téléchargés et je passe un DataContext pour valider un email n'est pas déjà pris.

      va fou avec ceci, c'est un énorme avantage de la flueuretvalidation, assurez-vous simplement que la dépendance n'est pas coûteuse en ce qui concerne le temps et les ressources.


1 commentaires

Merci @khalid. Je suis complètement d'accord avec toi.



4
votes

Je viens de regarder cela moi-même en utilisant l'unité et le MVC 4.

Ce que j'ai vu, c'est que si vous les gardez comme des objets transitoires. La flueuretvalidation créera un nouvel objet de validation pour chaque propriété validée. Donc, une certaine mise en cache est requise. P>

Pour ma mise en cache, j'ai examiné la mise en cache de la demande du validateur. Cela fonctionne bien que tous les composants dépendants sont par demande. (Par demande est le code personnalisé qui stocke un conteneur d'unité enfant sur les collections httpcontext.current.items avec un module HTTP qui détruit / dispose du conteneur enfant à la fin de la demande) P>

Pour choisir entre la demande et les instants singletons du validateur se résument à la manière dont votre utilisation et quel type de dépendances il a et les capacités du continent du CIO. p>

avec unité Vous pouvez créer un validateur singleton et injecter l'usine de service en utilisant un fonctionner à savoir Func Servicefunc. P>

Dans mon cas Chaque fois que j'appelle le servicefunc, le "service" Unity ChildrContiner est récupéré. Ainsi, je peux toujours avoir mon «validateur» défini avec un conteneur -rolledlifetimeMeManager (singleton) et avoir le «service» défini avec HierarchicalifetimeManager (par demande). P>

Un inconvénient de ceci est à chaque fois que le servicefunc est invoqué qu'il doit vérifier et récupérer le service du conteneur enfant. Ce sera la raison la plus probable pour laquelle je reviendrai sur "par demande") p>

Je viens de mettre à jour mon code pour utiliser Servicefunc et le testera aujourd'hui. Je crois que ce sera essai une erreur de trouver la solution appropriée pour vos aplications. P>

ci-dessous est l'usine de validation que j'utilise - au lieu d'utiliser le conteneur Unity (comme la plupart des exemples sur le Web), Je suis injectant le idependencyResolver code> et en l'utilisant pour résoudre mes objets de validateur. P>

public class ValidatorFactory : IValidatorFactory 
{
    private readonly IDependencyResolver _dependencyResolver;

    // taken from the attribute Validation factory
    public ValidatorFactory(IDependencyResolver dependencyResolver)
    {
        _dependencyResolver = dependencyResolver;
    }

    /// <summary>
    /// Gets a validator for the appropriate type.
    /// 
    /// </summary>
    public IValidator<T> GetValidator<T>()
    {
        return (IValidator<T>)this.GetValidator(typeof(T));
    }

    /// <summary>
    /// Gets a validator for the appropriate type.
    /// 
    /// </summary>
    public virtual IValidator GetValidator(Type type)
    {
        if (type == (Type)null)
            return (IValidator)null;
        var validatorAttribute = (ValidatorAttribute)Attribute.GetCustomAttribute((MemberInfo)type, typeof(ValidatorAttribute));
        if (validatorAttribute == null || validatorAttribute.ValidatorType == (Type) null)
        {
            return (IValidator) null;
        }
        else
        {
            return _dependencyResolver.GetService(validatorAttribute.ValidatorType) as IValidator;
        }
    }
}


1 commentaires

Merci Edys pour votre réponse