2011-05-17 3 views
6

J'ai cette classe:interfaces Agrégation en C#

class UrlManagementServiceClient : System.ServiceModel.ClientBase<IUrlManagementService>, IUrlManagementService 

ClientBase met en œuvre IDisposable et ICommunicationObject. J'ai aussi cette interface:

interface IUrlManagementProxy : IUrlManagementService, ICommunicationObject, IDisposable 

Mais je ne peux pas jeter UrlManagementServiceClient objets à IUrlManagementProxy. Y a-t-il un moyen d'accomplir cela? Je veux finir avec un objet qui peut accéder à toutes les méthodes sur les trois interfaces.

Répondre

4

Vous ne pouvez diffuser que vers des interfaces dont vous héritez. Pour pouvoir convertir le contenu en IUrlManagementProxy, vous devez implémenter cette interface.

class UrlManagementServiceClient : 
    System.ServiceModel.ClientBase<IUrlManagementService>, IUrlManagementProxy 

Vous pouvez ensuite lancer UrlManagementServiceClient soit UrlManagementProxy, IUrlManagementService, ICommunicationObject ou IDisposable.

Modifier
Les classes générées WCF sont partielles, cela signifie que vous pouvez étendre la définition de la classe dans un autre fichier. Mettre

public partial class UrlManagementServiceClient : IUrlManagementProxy {} 

dans un autre fichier de code et votre classe mettra en œuvre votre interface complète IUrlManagementProxy aussi, et vous pouvez alors le jeter aux IUrlManagementProxy.

+0

UrlManagementServiceClient est un client WCF généré automatiquement. J'aimerais éviter les modifications manuelles dans le fichier au cas où il devrait être re-généré. – RandomEngy

+0

@RandomEngy, Vous pouvez ajouter une définition de classe partielle avec votre propre interface dans un fichier séparé, voir la modification de ma réponse. –

+0

Nice. Propre et simple. – RandomEngy

1

Marque UrlManagementServiceClient mettre en œuvre IUrlManagementProxy au lieu de IUrlManagementService

class UrlManagementServiceClient : System.ServiceModel.ClientBase<IUrlManagementProxy>, IUrlManagementProxy 
0

Vous devez mettre en œuvre IUrlManagementProxy sur UrlManagementServiceClient. Il n'y a pas d'autre moyen - c'est un séparé type.

0

Vous ne pouvez évidemment pas convertir un objet en une interface qu'il n'implémente pas.

Mais, ce que vous pouvez faire (s'il est logique de mettre en œuvre toutes les méthodes pour chacune de ces interfaces sur un UrlManagementServiceClient exemple), est à wrap votre UrlManagementServiceClient dans un objet qui implémente les interfaces dont vous avez besoin.

Ceci est appelé le Decorator pattern (plutôt que le proxy). Un proxy "semble" être l'objet sous-jacent, alors que dans ce cas, vous ajoutez des fonctionnalités que votre client n'a pas.

En d'autres termes, vous auriez besoin d'une nouvelle classe:

public class UrlManagementClientProxy : IUrlManagementProxy 
{ 
    // we need a reference to the underlying client 
    private readonly UrlManagementServiceClient _client; 

    // underlying client is passed to the proxy in constructor 
    public UrlManagementClientProxy(UrlManagementServiceClient client) 
    { 
     _client = client; 
    } 

    #region IUrlManagementProxy methods 

    // you implementation goes here. if the underlying client 
    // already implements a certain method, then you just need 
    // to pass the call 

    // for example, client already implements methods 
    // from the IUrlManagementService interface, so use them 

    public string GetUrl() // made up 
    { 
      return _client.GetUrl(); 
    } 

    #endregion 
} 

Cela vous permet de réutiliser la mise en œuvre du client, et d'ajouter des fonctionnalités supplémentaires au-dessus de celui-ci.

+0

J'ai essayé cela, mais il y a beaucoup de choses à mettre en œuvre sur ICommunicationObject et IUrlManagementService et ça devenait compliqué. Je suis allé avec une autre approche. – RandomEngy

0

Pour résoudre ce problème, je viens de prolonger la classe et a déclaré l'interface globale sur elle:

public class UrlManagementProxy : UrlManagementServiceClient, IUrlManagementProxy 
{ 
    public UrlManagementProxy(Binding binding, EndpointAddress remoteAddress) 
     : base(binding, remoteAddress) 
    { 
    } 
} 

Puis-je utiliser UrlManagementProxy au lieu de UrlManagementServiceClient.Je n'ai besoin que de passer par les constructeurs dont j'ai besoin. Tout le reste est géré automatiquement. De cette façon, je n'ai pas besoin de modifier le UrlManagementServiceClient pour pouvoir le générer de nouveau et tout fonctionnera encore.