Question

DTO

Je construis une application Web, je voudrais à l'échelle à de nombreux utilisateurs. , Je dois aussi d'exposer la fonctionnalité à des tiers de confiance via les services Web.

J'utilise LLBLGen pour générer la couche d'accès aux données (en utilisant SQL Server 2008). L'objectif est de construire une couche logique métier qui protège le Web App des détails de DAL et, bien sûr, de fournir un niveau de validation supplémentaire au-delà du DAL. De plus, pour autant que je peux dire en ce moment, le service Web sera essentiellement une enveloppe mince sur la BLL.

Le DAL, bien sûr, a son propre ensemble d'objets d'entité, par exemple, CustomerEntity, ProductEntity, et ainsi de suite. Cependant, je ne veux pas la couche de présentation pour avoir accès à ces objets directement, car ils contiennent des méthodes spécifiques DAL et l'assemblage est spécifique au DAL et ainsi de suite. Donc, l'idée est de créer des objets de transfert de données (DTO). L'idée est que ces sera, essentiellement, bon vieux C # /. Objets NET qui ont tous les champs de, disons, un CustomerEntity qui sont en fait la table de base de données client, mais aucun des autres choses, sauf peut-être quelques propriétés IsChanged / de IsDirty. Donc, il y aurait CustomerDTO, ProductDTO, etc. Je suppose que ceux-ci hériteraient d'une classe de DTO de base. Je crois que je peux générer avec ces templates pour LLBLGen, mais je ne suis pas sûr encore.

Alors, l'idée est que le BLL exposera ses fonctionnalités en acceptant et le retour de ces objets DTO. Je pense que le service Web traitera la conversion de ces objets en XML pour les tiers à l'utiliser, beaucoup ne peuvent utiliser des .NET (aussi, certaines choses seront scripts appelable de AJAX appelle le Web App, en utilisant JSON).

Je ne suis pas sûr de la meilleure façon de concevoir ce et exactement comment aller de l'avant. Voici quelques questions:

1) Comment devrait-il être exposé aux clients (Le niveau de la présentation et au code de service Web)

Je pensais qu'il y aurait une classe publique qui a ces méthodes, chaque appel serait être une opération atomique:

InsertDTO, UpdateDTO, DeleteDTO, GetProducts, GetProductByCustomer, et ainsi de suite ...

Ensuite, les clients seraient simplement appeler ces méthodes et de passer dans les arguments appropriés, généralement un DTO.

Est-ce une bonne approche viable?

2) Que revenir de ces méthodes? De toute évidence, Get / Fetch genre de méthodes retournera DTO. Mais qu'en est-Insertions? Une partie de la signature pourrait être:

InsertDTO(DTO dto)

Cependant, lorsque vous insérez ce qui devrait être de retour? Je veux être informé des erreurs. Cependant, j'utilise les clés primaires autoincrementing pour certaines tables (Cependant, quelques tables ont des clés naturelles, en particulier beaucoup à beaucoup de ceux).

Une option que je pensais était une classe de résultats:

class Result
{
    public Exception Error {get; set;}
    public DTO AffectedObject {get; set;}
}

Alors, sur un insert, la DTO obtiendrait son ID get (comme CustomerDTO.CustomerID) jeu de propriétés, puis mis dans cet objet résultat. Le client sait s'il y a une erreur si Result.Error! = Null et il serait alors connaître l'ID de la propriété Result.AffectedObject.

Est-ce une bonne approche? Un problème est qu'il semble que ce passe beaucoup de données avant et en arrière qui est redondant (quand il est juste l'ID). Je ne pense pas que l'ajout d'une propriété « int NewID » serait propre parce que certains inserts ne seront pas une clé de autoincrementing comme ça. Une autre question est que je ne pense pas que les services Web traiteraient ce bien? Je crois qu'ils simplement retourner le DTO de base pour AffectedObject dans la classe de résultat, plutôt que la DTO dérivée. Je suppose que je pouvais résoudre ce problème en ayant un grand nombre de différents types d'objets de résultat (peut-être issus d'un résultat de base et hériteront la propriété d'erreur), mais cela ne semble pas très propre.

D'accord, j'espère que ce ne soit pas trop verbeux, mais je veux être clair.

Était-ce utile?

La solution

1: C'est une approche assez standard, qui se prête bien à une mise en œuvre « référentiel » pour la meilleure approche unitaire testable

.

2: Exceptions (qui doivent être déclarés comme « fautes » sur la frontière WCF, btw) se sont soulevées automatiquement. Vous n'avez pas besoin de gérer directement. Pour les données - il y a trois approches communes:

  • utilisation ref sur le contrat (pas très joli)
  • retourner le (mise à jour) objet - à savoir public DTO SomeOperation(DTO item);
  • juste retour des informations d'identité mises à jour (clé primaire / horodatage / etc)

Une chose à propos de tous ces est qu'il ne nécessite pas un autre type par opération (contraste de votre classe Result, qui aurait besoin d'être dupliqué par DTO).

Autres conseils

Q1: Vous pouvez penser à vos types composites de données WCF contrat comme DTO pour résoudre ce problème. De cette façon, votre couche d'interface utilisateur n'a accès aux propriétés DataMember du DataContract. Vos opérations atomiques seraient les méthodes exposées par votre interface WCF.

Q2:. Configurez vos contrats de données de réponse pour renvoyer un nouveau type personnalisé avec vos clés primaires etc ... WCF peut également être configuré pour des exceptions à bulles de retour à l'interface utilisateur

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