2010-05-28 10 views
2

Donc j'apprends WCF et j'ai rencontré un problème que je crois avoir à faire avec Instance Control/State mais je ne suis pas sûr.Simple WCF question

Le flux de travail est le suivant: paradigme client/serveur de base.

  1. Le client appelle une méthode RetrieveBusinessObjects (critères) et le serveur appelle la couche de données et les met alors dans un IList du côté du serveur. Il ne renvoie pas cette liste au client appelant.

  2. Le client appelle alors une méthode, par exemple DisplayBusinessObjects(), qui récupère l'IList du serveur, le sérialise, l'amène sur le réseau et l'affiche.

Si j'essaye ceci en utilisant le WCFTestClient cela fonctionne. Si je l'exécute à partir d'un client réel, je récupère un objet BusinessObject [] de taille 0. Ce qui pour moi indique que je n'avais aucun objet à retourner.

Est-ce un problème d'état mgmt ou est-ce que je manque quelque chose?

+0

postez votre code/contrat s'il vous plaît. – kd7

+1

Pourquoi ne pas simplement avoir un seul appel pour ça? Demandez à vos 'DisplayBusinessObjects' de faire le travail des deux. Ensuite, vous pouvez garder la nature apatride. – Justin

Répondre

3

Vous devez prendre en compte ceci: par défaut, chaque appel à un service WCF aboutira à une instance fraîchement créée de votre classe de service. Donc, si votre premier appel à RetrieveBusinessObjects (.....) arrive, une nouvelle instance de la classe de service est instanciée, les éléments sont récupérés et stockés dans l'instance d'objet - et quand l'appel est terminé, l'instance est éliminé. Votre deuxième appel à DisplayBusinessObjects() recevra à nouveau une nouvelle instance de la classe de service - et il n'a aucune connaissance de l'appel précédent, donc il ne peut rien avoir dans son tableau BusinessObject - c'est une nouvelle instance, après tout.

Ce type de scénario ne fonctionne pas correctement: vous devez réorganiser votre solution pour qu'un appel unique récupère et renvoie la liste des objets métier, puis les cache sur le client. Vous devez également utiliser un cache/stockage permanent sur le serveur pour mettre en cache les éléments récupérés entre les appels.

+0

Bien placé! (15 caractères) – Nate

0

Je suis d'accord avec @marc_s, en ce sens que vous devriez envisager de rendre vos opérations de service plus grossières, et envisager de les combiner en une seule opération. Vous n'indiquez pas pourquoi votre premier appel doit stocker les données dans la couche de service et ne les renvoie que dans le second appel.

Cependant, si vous avez absolument besoin de cette approche dans votre mise en œuvre de services, vous pouvez mettre en œuvre le service à l'aide par session instanciation:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] 
public class MyService : IService 
{ 
    private MyState _myState; 

    public MyService() 
    { 
     _myState = new MyState(); 
    } 

    public void RetrieveBusinessObjects(...) 
    { 
     _myState.Items = GetDataFromDataLayer(); 
    } 

    public IList<Item> DisplayBusinessObjects() 
    { 
     return _myState.Items; 
    } 
} 

Cela garantit que chaque client obtient sa propre instance du service, et c'est l'état interne. Cependant, cette approche n'est pas particulièrement bien adaptée, alors vous devrez peut-être vous pencher là-dessus avant de décider.