2009-10-16 5 views
2

aidez-moi à résoudre ce problème.Besoin d'un moyen de fermer un ChannelFactory lorsque le client ne connaît que l'interface

J'ai un client utilisant WCF. Je ne veux pas que ce client sache qu'il obtient ses données d'un service. Je veux utiliser un modèle comme celui-ci, donc il m'est plus facile de tester le code un par un et de remplacer plus tard l'implémentation de l'interface donnée. Le problème avec ce modèle est que je ne suis pas en mesure d'appeler de près sur le ChannelFactory. Je ne suis pas sûr que j'ai besoin d'appeler de près, mais ça me semble juste.

Ma question est la suivante:

Quelqu'un sait-il d'un bon modèle pour fermer le ChannelFactory lorsque le client ne devrait connaître l'interface du service? Ou est-ce que le ChannelFactory est fermé par une sorte de magie?

est Ci-dessous un exemple de code que j'espère vous comprendre la question:

static void Main(string[] args) 
    { 
     ITestService service = GetTestService(); 
     Console.WriteLine(service.GetData(42)); 

    } 

    private static ITestService GetTestService() 
    { 
     var cf = new ChannelFactory<ITestService>(new WSHttpBinding(), new EndpointAddress("http://localhost:8731/TestService/")); 
     return cf.CreateChannel(); 
    } 

Merci, GAT

Répondre

4

La meilleure façon de résoudre ce problème est de maintenir la référence au ChannelFactory en vie aussi Tant que vous en avez besoin. Donc prenez la création du ChannelFactory sur la méthode GetTestService et créez l'usine à l'initialisation de votre classe (dans le constructeur par exemple) et fermez-la lorsque vous n'avez plus besoin de l'usine (dans la méthode Dispose de votre classe par exemple).

ChannelFactory est une classe d'usine que vous pouvez réutiliser autant de fois que vous le souhaitez, donc il n'y a pas besoin de créer chaque fois que vous avez besoin d'une mise en œuvre de services.

+0

Cela ressemble à une bonne solution. Donc, ce que je peux faire est d'avoir ma propre "ServiceFactory" qui contient une chaîne statique . Chaque fois que j'ai besoin d'un canal, j'appellerai CreateChannel() sur ce membre. Et quand l'application est terminée, j'appelle close sur la ChannelFactory. Est-ce que cela semble être la bonne façon de procéder? – GAT

+0

C'est la bonne façon. Le point principal est que vous ne devriez pas créer une nouvelle ChannelFactory chaque fois que vous avez besoin d'un canal. Il n'y a aucun problème à garder une ChannelFactory active pendant toute la durée du programme. –

2

Vous devez implémenter la classe comme

public class MyClient : ITestService 
{ 
private ChannelFactory<ITestService> factory; 
private ITestService proxy; 
//... 
//expose here methods Open and Close that internally will open and close channel factory 
//implement interface members 
} 

La durée de vie du client ici sera la même chose que la vie de l'usine de canal.

+0

Cela semble aussi une bonne solution. Donc ce que vous voulez que je fasse est de faire un emballage pour mon service que je peux utiliser dans mon application? – GAT

+0

J'ai accepté la réponse de @rwwilden depuis qu'il a répondu en premier. Je pense que les deux réponses étaient très bonnes, alors j'ai voté pour votre réponse. – GAT

1

Avez-vous essayé de le convertir en IClientChannel puis d'appeler Close?

((IClientChannel)service).Close(); 
+0

Je suppose que cela fonctionnerait. Mais je ne veux pas que mon client connaisse IClientChannel. Cela détruirait mon test unitaire puisque mon FakeService n'implémente pas IClientChannel. – GAT

+0

Yeap - personnellement, j'irais avec la solution de rwwilden. J'allais ajouter cela mais ma connexion Internet a chuté dans le train! – RichardOD

+0

Je suppose que vous utilisez l'opérateur C# comme opérateur à la place et appelez seulement Close si ce n'est pas null. Cela permettrait à vos tests unitaires de ne pas échouer - voir ici: http://msdn.microsoft.com/fr-fr/library/cscsdfbt.aspx – RichardOD

Questions connexes