Aggregating interfaces in C#
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.
精彩评论