在 C# 中聚合接口
本文关键字:接口 | 更新日期: 2023-09-27 17:56:50
我有这个类:
class UrlManagementServiceClient : System.ServiceModel.ClientBase<IUrlManagementService>, IUrlManagementService
客户群实现IDisposable
和ICommunicationObject
。我也有这个界面:
interface IUrlManagementProxy : IUrlManagementService, ICommunicationObject, IDisposable
但我不能UrlManagementServiceClient
对象投射到IUrlManagementProxy
.有没有办法做到这一点?我想得到一个可以访问所有三个接口上的所有方法的对象。
您只能强制转换为继承自的接口,以便能够强制转换为需要实现该接口IUrlManagementProxy
。
class UrlManagementServiceClient :
System.ServiceModel.ClientBase<IUrlManagementService>, IUrlManagementProxy
然后,您可以将UrlManagementServiceClient
转换为 UrlManagementProxy
、 IUrlManagementService
、 ICommunicationObject
或 IDisposable
。
编辑
WCF 生成的类是部分的,这意味着您可以在另一个文件中扩展类定义。放
public partial class UrlManagementServiceClient : IUrlManagementProxy {}
在另一个代码文件中,您的类也将实现您的完整IUrlManagementProxy
接口,然后您可以将其转换为 IUrlManagementProxy
。
使UrlManagementServiceClient
实现IUrlManagementProxy
而不是IUrlManagementService
class UrlManagementServiceClient : System.ServiceModel.ClientBase<IUrlManagementProxy>, IUrlManagementProxy
您需要在UrlManagementServiceClient
上实现IUrlManagementProxy
。没有其他方法——它是一个单独的类型。
显然,您不能将对象强制转换为它未实现的接口。
但是,您可以做的(如果从UrlManagementServiceClient
实例中为每个接口实现所有方法有意义)是将您的UrlManagementServiceClient
包装在实现所需接口的对象中。
这称为装饰器模式(而不是代理)。代理通常"看起来"是底层对象,而在这种情况下,您正在添加客户端没有的功能。
换句话说,您将需要一个新类:
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
}
这允许您重用客户端的实现,并在其上添加其他功能。
为了解决这个问题,我只是扩展了类并在其上声明了聚合接口:
public class UrlManagementProxy : UrlManagementServiceClient, IUrlManagementProxy
{
public UrlManagementProxy(Binding binding, EndpointAddress remoteAddress)
: base(binding, remoteAddress)
{
}
}
然后我用UrlManagementProxy
而不是UrlManagementServiceClient
.
我只需要通过我需要的构造函数。其余的都是自动处理的。同样这样,我不需要修改UrlManagementServiceClient
,因此我可以重新生成它,一切仍然可以正常工作。