开发者

Aggregating interfaces in C#

开发者 https://www.devze.com 2023-03-06 19:23 出处:网络
I\'ve got this class: class UrlManagementServiceClient : System.ServiceModel.ClientBase<IUrlManagementService>, IUrlManagementService

I've got this class:

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

ClientBase implements IDisposable and ICommunicationObject. I've also got this interface:

interface IUrlManagementProxy : IUrlManagementService, ICommunicationObject, IDisposable

But I can't cast UrlManagementServiceClient objects to IUrlManagementProxy. Is there some way to accomplish this? I want to end up with an object that can access all the methods on all 开发者_如何学Gothree interfaces.


You can only cast to interfaces that you inherit from, to be able to cast to IUrlManagementProxy you need to implement that interface.

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

You can then cast UrlManagementServiceClient to either UrlManagementProxy, IUrlManagementService, ICommunicationObject or IDisposable.

Edit
The WCF-generated classes are partial, that means that you can extend the class definition in another file. Put

public partial class UrlManagementServiceClient : IUrlManagementProxy {}

in another code file and your class will implement your full IUrlManagementProxy interface too and you can then cast it to IUrlManagementProxy.


Make UrlManagementServiceClient implement IUrlManagementProxy instead of IUrlManagementService

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


You need to implement IUrlManagementProxy on UrlManagementServiceClient. There's no other way — it's a separate type.


You obviously cannot cast an object to an interface which it doesn't implement.

But, what you can do (if it makes sense to implement all methods for each of those interfaces out of an UrlManagementServiceClient instance), is to wrap your UrlManagementServiceClient in an object which implements the interfaces you need.

This is called the Decorator pattern (rather than proxy). A proxy usually "appears" to be the underlying object, while in this case you are adding functionality which your client doesn't have.

In other words, you would need a new class:

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
}

This allows you to reuse client's implementation, and add additional functionality on top of it.


To solve this, I just extended the class and declared the aggregate interface on it:

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

Then I use UrlManagementProxy instead of UrlManagementServiceClient.

I only need to pass through constructors that I need. All the rest is handled automatically. Also this way I don't need to modify the UrlManagementServiceClient so I can re-generate it and everything will still work.

0

精彩评论

暂无评论...
验证码 换一张
取 消