39 votes

WCF Service Reference génère sa propre interface de contrat, ne réutilisera pas la mienne

Ma première question donc j'espère que c'est approprié:

Interface partagée de l'assemblée - j'ai un "partage" de l'assemblée, qui dispose d'une interface, appelons - IDocRepository. Il est marqué par [ServiceContract] et il y a plusieurs [OperationContract]-marqué méthodes.

WCF la mise en œuvre des assemblages - j'ai deux service WCF projets, faisant chacun référence à l'assembly partagé, chaque implémentant cette interface, comme un service WCF.

Assemblée des consommateurs, - Enfin, j'ai un "client" du projet, également référence le partage de l'assemblée, avec une référence à chacun des deux services WCF.

Cependant, le service de références générées dans l'assemblée des consommateurs, qui proviennent d'une auto-généré version de l'interface:

public partial class ExampleClient : System.ServiceModel.ClientBase<SomeNamespace.ExampleSvcRef.IDocRepository>, SomeNamespace.ExampleSvcRef.IDocRepository {

De ce que j'attendais
J'aurais espéré que les deux références au lieu héritent automatiquement l'interface que j'ai défini, que le consommateur/client assemblée est également le référencement. Un peu comme la réutilisation de classes qu'il fournit pour le paramètre et les types de retour, mais pour l'interface de service.

Pourquoi
Afin que je puisse créer une instance de service de référence de proxy et de voter pour elle à mon type d'interface.

J'ai donc pu modifier le code généré par la main à chaque fois, mais il devrait y avoir une meilleure façon...?

(edit: j'ai "Réutiliser les types dans les assemblys référencés" et "la Réutilisation des types dans tous les assemblys référencés" options sélectionnées pour les deux références de service)

46voto

Quartermeister Points 24729

"La réutilisation des types dans les assemblys référencés" ne vous permet de réutiliser les Données des Contrats, et non des Contrats de Service. Si vous voulez partager des Contrats de Service, vous n'avez pas besoin d'utiliser la fonction "Ajouter une Référence de Service" à tous. Vous pouvez simplement utiliser ChannelFactory directement.

// Supply the binding and address in code
Binding binding = new BasicHttpBinding();
EndpointAddress address = new EndpointAddress("http://tempuri.org/address");
IServiceContract channel = ChannelFactory<IServiceContract>.CreateChannel(binding, address);

// Or read them from the config file
ChannelFactory<IServiceContract> channelFactory = new ChannelFactory<IServiceContract>();
IServiceContract channel = channelFactory.CreateChannel();

Le canal de l'objet également de mettre en œuvre ICommunicationObject, de sorte que vous pouvez le jeter si vous avez besoin d'appeler des méthodes comme Open() ou Close().

4voto

David M Points 45808

Lorsque vous créez la référence de service, vous pouvez cocher une case pour lui faire réutiliser les définitions partagées. Assurez-vous que le projet client fait déjà référence à l'assembly partagé, ajoutez à nouveau la référence de service et vérifiez soigneusement toutes les options.

Si cela ne fonctionne toujours pas, vérifiez la liaison que vous utilisez. J'ai un vague souvenir que la liaison HTTP de base ne prend pas en charge la réutilisation des types?

3voto

Ron Deijkers Points 297

Visual Studio ne prend pas en charge la réutilisation de vous interface existant lors de la création des classes de proxy pour vous. La réutilisation des types pas réutiliser le contrat d'interface comme Quartermeister souligné.

Nous avons résolu avec l'héritage. Assez similaire à la classe partielle idée ci-dessus proposé par le Bouffon du Logiciel.

C'est la façon dont nous l'avons résolu:

Dans le projet de votre client, il suffit de créer un service de référence comme vous l'auriez fait. Puis ajouter une classe qui sert de remplacement pour le client:

internal class MyServiceProxy : MyServiceClient, MyLogicNamespace.IMyService
{}

Cette classe hérite de la MyServiceClient mais affirme que son client n'mettre en œuvre l'interface d'origine.

(Je vous conseille de les mettre dans un dossier nommé "ServiceProxies")

Si le MyServiceClient classe contient des méthodes qui ne correspondent pas à l'original de l'interface alors vous pouvez les ajouter dans ce proxy et de faire la conversion dans le code.

Après cela, il suffit d'utiliser la MyServiceProxy où vous auriez utilisé MyServiceClient.

2voto

Il y a une autre bonne option, si vous souhaitez continuer à utiliser le générateur de proxy pour elle est limitée-mais-un peu-de fonctionnalité utile... Utiliser une classe partielle:

namespace <same namespace as generated proxy>
{
    public partial class MyClient : <namespace of "real" service contract>.IServiceContract
    {
    }
}

S'assurer que le proxy est de générer du code à la même manière que votre Contrat de Service est de le définir, c'est à dire, si c'est à l'aide de "Liste", utilisez cette option dans configuration du Service de Références ainsi. En d'autres termes, assurez-vous que votre Service générée Interface est exactement égal à votre Service réel de l'Interface et le code ci-dessus devrait fonctionner, et de mettre à jour la référence que vous utilisez clic droit au lieu de l'écriture de code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X