2012-06-27 3 views
2

Quelles sont les solutions pour la persistance des données dans un service Web .NET?Persistance des données dans les services Web?

J'ai un webservice. Je donne un identifiant à mon webservice et celui-ci renvoie l'objet correct.

 [OperationContract] 
     [WebInvoke(Method = "GET", UriTemplate = "/GetMyObject?id={id}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] 
     MyObject GetMyObject(string id); 

Je ne veux pas utiliser une base de données. Je voudrais garder ma collection d'objets en "mémoire". J'ai donc décidé de créer un objet simple dans mon webservice comme celui-ci

public class Service : IService 
    { 
     List<MyObject> list = new List<MyObjec>(); 

     public Service() 
     { 
      list.Add(new MyObject() { Id = 1, Data = ...}); 
      list.Add(new MyObject() { Id = 2, Data = ...}); 
      list.Add(new MyObject() { Id = 3, Data = ...}); 
      list.Add(new MyObject() { Id = 4, Data = ...}) 
      ... 
     } 

     public MyObject GetMyObject(string id) 
     { 
      // code to get my object from the list 
      return myObject; 
     } 
} 

Il fonctionne, mais le constructeur est appelé chaque fois que j'appelle mon webservice et je voudrais initialiser cette liste une fois et appliquer la modification à ce sujet plus tard. Comment dois-je initialiser ma liste et persiste-t-il?

+0

En ce moment je ne me soucie pas de la concurence mais oui dans une solution finale je vais devoir utiliser autre chose qu'une liste. –

+0

Je ne suis pas sûr de la définition de la persistance des données dans les services Web. Souhaitez-vous que les données soient persistantes si vous deviez redémarrer le service et le serveur, en effaçant toute la mémoire? –

Répondre

8

Vous pouvez utiliser une collection statique:

private static List<MyObject> list = new List<MyObjec>(); 

et bien sûr puisque c'est une application multithread où vous pourriez éventuellement avoir un accès simultané à cette collection, vous devez vous assurer de synchroniser l'accès. Ou si vous utilisez .NET 4.0 il suffit d'utiliser un thread-safe ConcurrentBag<T>:

private static ConcurrentBag<MyObject> list = new ConcurrentBag<MyObjec>(); 

Bien sûr, vous devez parfaitement bien être conscient qu'en utilisant une structure en mémoire pour stocker vos données de votre vie de données est essentiellement liée à la vie de l'application web. Et puisque IIS peut recycler le domaine d'application à tout moment (une certaine période d'inactivité, certains seuils CPU/mémoire sont atteints) tout ce que vous avez stocké dans la mémoire va dans le vide. D'ailleurs, si vous suivez cette route, soyez préparé à ce que cela arrive très souvent, chaque fois que vous recompilez votre service web, car en recompilant, vous modifiez les assemblages dans le dossier bin et le serveur web va simplement recycler le application. Donc, oui, tout ce mur de texte pour vous dire de persister vos données ailleurs qu'en mémoire :-) Vous avez tellement de possibilités allant des fichiers dans différents formats, bases de données, bases de données embarquées, ...

+0

Et comment puis-je initier ma liste une fois lorsque je démarre mon projet de service web? –

+1

Vous pouvez utiliser un [constructeur statique] (http://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx) pour la classe de service Web qui est garantie par le CLR pour être appelée une seule fois par durée de vie AppDomain. –

3

vous pouvez faire votre service un singleton

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, 
       ConcurrencyMode = ConcurrencyMode.Single)] 
class Service 
... 

Cependant, cette approche conduit à des problèmes énormes à l'avenir. Ne stockez rien en mémoire. Si vous le faites, vous intégrez un état dans l'application. Cela conduit à une énorme quantité de travail nécessaire pour atteindre une fiabilité et une évolutivité élevées. Pas d'état, pas de douleur.

+0

Si vous faites cela, vous ne devriez plus utiliser 'List ' car si vous avez 2 appels simultanés de la méthode web, vous obtiendrez des données corrompues. –

+0

@oleksii Cette solution est-elle performante pour un webservice qui sera appelé tout le temps?chaque milliseconde par de nombreux ordinateurs? –

+0

@DarinDimitrov oui vous avez raison, j'ai ajouté 'ConcurrencyMode.Single' pour cela. Sinon, Dran peut utiliser 'ConcurrantBag ' après votre réponse. – oleksii

Questions connexes