2011-04-01 7 views
1

Je suis en train de redessiner l'architecture d'une solution pour mettre en œuvre SOA.Architecture SOA pour ASP.NET avec Entity Framework

Après avoir fait les changements de conception que je suis venu avec:

  • MySolution.Client.MyProject.Web ...... //ASP.NET WebSite
  • MySolution.Client.MyProject.Proxy .... // Projet de bibliothèque C# Proxy de service * 1
  • MySolution.Service ................... //Service.cs pour Service.svc is here
  • MySolution.Service.DataContract ...... //IService.cs pour Service.cs est ici * [2]
  • MySolution.Service.HttpHost .......... //Service.svc est ici
  • MySolution.Model ..................... // Toutes les classes de données personnalisées et le modèle EDMX sont ici * [3]
  • MySolution.Repository ................ // Le référentiel interroge la base de données à l'aide des requêtes LINQ et ADO.NET

* 1 MySolution.Client.MyProject.Proxy: Ce projet contient proxy de service et contient des classes de présentation

* [2] M ySolution.Service.DataContract:

  • Ce projet contient IService et demande/réponse Classes
  • Toutes les méthodes Service.cs prend les classes de demande en entrée et le retour des classes de réponse en sortie
  • Par conséquent, ce projet est référencé par les 2 projets clients (Web et proxy), car il contient le IService et toutes les classes de requête/réponse qui seront nécessaires pour communiquer avec Service.cs

* [3] MySolution.Model: Ce projet contient le fichier .edmx qui est le modèle de modèle d'entité de données et certaines classes personnalisées qui sont utilisées dans le projet.

PROBLÈME:

Parce que je n'utilise que des classes de demande/réponse pour communiquer entre le service et le client, le projet de MySolution.Service.DataContract est utilisé par Service.cs et Repository.cs

Et à cause de cela, toutes les réponses générées par le Repository doivent être mappées aux propriétés de sa classe de réponse respective (ce qui rend l'entité retournée originale et la classe de réponse presque identique). Mais je suis d'accord avec ça ...

Par exemple:

  • Le GetCustomer() dans la méthode Repository.cs est appelée par Service.cs
  • La méthode GetCustomer() dans le dépôt effectue le LINQ interroger et renvoyer un objet "Client"
  • Service.cs mappe alors toutes les propriétés de l'objet "Client" à l'objet "CustomerResponse"
  • Service.cs renvoie ensuite "CustomerResponse" à l'appelant.

Dans ce cas, la plupart des propriétés se répètent dans les deux classes. S'il y a une solution, c'est bien, sinon, ça me va.

Toutefois, lorsque les GetCustomers méthode de Repository.cs() (avis ce n'est pas GetCustomer()) est appelée, elle renvoie une liste d'objets clients, et cartographier ce à des fins de retour signifierait une « boucle » qui itère la collection et fait le mapping ... Ce n'est pas OKAY ...

Y a-t-il une meilleure façon de faire cela, étant donné que je ne veux pas retourner l'objet "Client" sans "CustomerResponse" comme d'abord viole l'architecture SOA, et deuxièmement, je ne veux pas que mes projets clients aient une référence aux projets Model ou Repository?

Répondre

2

Alors, est-ce juste le mappage que vous rencontrez? Si oui, vous pouvez regarder quelques bibliothèques de cartographie open source comme Mapper Extensions ou AutoMapper qui automatisera la tâche.

+0

Yeh, le problème principal est Mapping, plus aussi, je dois créer exactement les mêmes classes pour créer une classe Response à nouveau; bien que les classes soient déjà générées par l'Entity Framework ... en passant, est-ce une bonne approche pour hériter de la classe Response de la classe généréeEntityFramework? Je ne suis pas sûr si cela héritera seulement des propriétés, ou héritera de toutes les autres fonctionnalités, comme quand un nouvel objet est créé, et la méthode Save est appelée, elle ajoute une nouvelle ligne dans la DB ... ??? – user402186

+0

Eh bien, je suppose que je devrais peut-être comprendre pourquoi vous utilisez les objets de réponse en premier lieu avant de répondre ... essayez-vous simplement d'abstraire la structure physique des données? – BrandonZeider

+0

yeh, dans la plupart des cas, mais dans d'autres, j'ajoute quelques propriétés supplémentaires aussi bien – user402186

1

Il semble que votre principal point de la douleur est la cartographie fastidieuse des objets de données à data transfer objects (DTO). Je ne l'ai pas utilisé moi-même, mais il semble que AutoMapper est faite pour faire des mappages automatiques d'objet à objet de façon déclarative.

Je certainement en tenir à avoir vos objets de données distincts des contrats de données dans vos services.

+0

s'il vous plaît voir le commentaire que j'ai fait sur le post de BrandonZeider ci-dessous – user402186

1

Si vous n'aimez pas le mappage séparé entre entités et DTO, exposez IQueryable dans votre référentiel et utilisez des projections directes vers les objets DTO. L'inconvénient est qu'une telle solution ne peut pas être effectivement testée à l'unité. Le fait de simuler le référentiel dans un tel scénario n'a aucun sens car la requête contre simule est Linq-to-objects alors que la requête par rapport au référentiel réel est Linq-to-entities (ensemble différent de fonctionnalités où la différence n'est visible qu'au moment de l'exécution).

Btw. Je ne vois pas trop de SOA dans votre application - je vois juste une application à plusieurs niveaux. C'est comme planter un arbre dans un jardin et dire que vous avez une forêt. De plus, il semble que vous construisiez l'interface CRUD (entités presque 1: 1 pour les DTO). J'ai le mauvais pressentiment que vous investissez trop d'efforts dans l'architecture dont vous n'avez pas besoin. Si votre intention principale est de construire des opérations CRUD exposées comme des services au-dessus de la base de données, vous pouvez exposer des entités directement de plus, vous pouvez utiliser des outils comme WCF Data services.

+0

Yeh dans la plupart des cas ce sont les entités sont 1: 1 à DTO, mais pas toujours. Peut être vous êtes rite, je n'ai pas besoin de SOA, mais je veux toujours l'implémenter, car j'aime l'architecture et la manière dont le client communique seulement par le service. Les projets Repository, Model sont également utilisés par 4 autres applications clientes, en utilisant leurs services distincts, mais le référentiel et le modèle sous-jacents sont identiques dans les 5 applications client. – user402186

+0

quelle serait la meilleure pratique à cet égard? c'est-à-dire (les entités sont 1: 1 à DTO), devrait-on créer à nouveau les mêmes classes DTO? – user402186

+0

5 services pour exposer les mêmes dépôts? Imho c'est plus contre la SOA que l'exposition de l'entité elle-même. Dans les services SOA, les services doivent être indépendants = aucune fonctionnalité partagée (y compris les données) entre les services. –