Question

Nous avons écrit un service Web qui utilise un simple traducteur d'entité pour cartographier les valeurs de DTO de retour sur côté serveur « vrais » objets métier. Dans le cadre de cette excercise. Nous avons rencontré une distinction "intéressante" entre explicitement définir des valeurs null et les clients ayant pas régler une valeur.

Le problème est essentiellement que nous voulons définir une valeur par défaut sur l'objet réel d'affaires si le client n'a pas explicitement défini une valeur , mais en utilisant les types standards nullables il n'y a pas moyen de savoir si un client a explicitement signifié " réglez ce paramètre sur null " ou tout simplement pas régler.

La solution ici est évidemment une sorte de « drapeau ».

Dans un objet métier, nous pouvons suivre l'état d'un champ interne en utilisant des drapeaux « de IsDirty » privées établies dans les setters de propriété, mais un DTO ne spécifie vraiment une interface si cela signifie exposer ces données au public. Cela laisse un certain nombre d'options de mise en œuvre. Le langage est C # (si statiquement typé) alors ...

  1. Nous pourrions exposer un drapeau « IsSet » sur chaque propriété?
  2. Nous pourrions exposer chaque propriété comme une classe qui possède une propriété .Value et .IsSet? etc etc.

Comment serait choisir d'exposer ces « drapeaux » sur le contrat de données? Que voulez-vous ici considèrent comme les meilleures pratiques pour cela?

Les avis sur ce serait grandement apprécié.

Était-ce utile?

La solution

En utilisant une classe pour chaque valeur de la propriété serait plus évolutive avoir à déclarer un bool pour chaque propriété. Il serait également vous permettre de choisir les propriétés sont en mesure d'être laissé vide et / ou des valeurs nulles.

Autres conseils

Vous pouvez écrire une classe qui enveloppe les drapeaux avec les données:

public class DtoData<T> 
{
  T data;
  bool IsSet { get; private set; }
  T Data 
  { 
    get { return data; }
    set { data = value; IsSet = true; } 
  }
}


public class XyzDto 
{
  // only private setters, initialize in constructor
  DtoData<int?> SomeInt { get; private set; }
  DtoData<string> SomeString { get; private set; }
}

a quelques inconvénients ainsi. Par exemple, que toutes vos données est enveloppé dans un type de référence, de sorte que la référence à DtoData pourrait encore être nulle, vous devez les créer dans un constructeur. Et il est difficile de rendre les valeurs accessibles uniquement interne ou protégées.


Personnellement, je voudrais essayer d'éviter ce problème. Pourquoi devrait « non défini » existent réellement? Envoyez-vous autour des différences, DTO incomplète, ou d'où vient-elle? Ce problème pourrait venir avec des filtres, où vous avez besoin d'une différence si vous filtrez un champ pour nul ou si vous ne filtrent pas du tout. Mais pour de tels scénarios, vous avez besoin d'un « filtre de champ » classe spéciale de toute façon.

En général, ce que vous parlez ici est une valeur par défaut qui est différente de toute valeur que l'utilisateur peut définir. Il suffit donc de préciser que; définir la valeur par défaut à une valeur qui se trouve pas dans la plage admissible de valeurs que l'utilisateur peut définir. De cette façon, si la valeur est la valeur par défaut, vous savez qu'il n'a pas été défini; si la valeur est autre chose que cela, vous savez que l'utilisateur a bricolé avec elle. Tout simplement parce que l'une des valeurs paramétrables par l'utilisateur est nul semble être vous jeter au large; juste le considérer comme l'un des l'ensemble des valeurs paramétrables; faire toute la plage de la variable, un ensemble légèrement plus grand, avec une valeur par défaut supplémentaire. Cela devrait résoudre votre problème.

Je suis tombé sur ce problème exact avant. Vous pouvez contourner ce problème en introduisant une certaine valeur par défaut sur la construction de la DTO, mais il est est pas idéal. Je blogué plus en détail ici , cela pourrait aider quelqu'un à comprendre la question.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top