【问题标题】:Aggregating interfaces in C#在 C# 中聚合接口
【发布时间】:2011-05-17 19:28:23
【问题描述】:

我有这门课:

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

ClientBase 实现了IDisposableICommunicationObject。我也有这个界面:

interface IUrlManagementProxy : IUrlManagementService, ICommunicationObject, IDisposable

但我不能将 UrlManagementServiceClient 对象转换为 IUrlManagementProxy。有没有办法做到这一点?我想最终得到一个可以访问所有三个接口上的所有方法的对象。

【问题讨论】:

    标签: c# .net interface


    【解决方案1】:

    您只能转换为您继承自的接口,为了能够转换为IUrlManagementProxy,您需要实现该接口。

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

    然后您可以将UrlManagementServiceClient 转换为UrlManagementProxyIUrlManagementServiceICommunicationObjectIDisposable

    编辑
    WCF 生成的类是部分的,这意味着您可以在另一个文件中扩展类定义。放

    public partial class UrlManagementServiceClient : IUrlManagementProxy {}
    

    在另一个代码文件中,您的类也将实现完整的IUrlManagementProxy 接口,然后您可以将其转换为IUrlManagementProxy

    【讨论】:

    • UrlManagementServiceClient 是一个自动生成的 WCF 客户端。我想避免手动编辑文件,以防需要重新生成。
    • @RandomEngy,您可以在单独的文件中使用自己的接口添加部分类定义,请参阅我的答案的编辑。
    【解决方案2】:

    使UrlManagementServiceClient 实现IUrlManagementProxy 而不是IUrlManagementService

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

    【讨论】:

      【解决方案3】:

      您需要在UrlManagementServiceClient 上实现IUrlManagementProxy。没有其他办法——它是一个单独的类型。

      【讨论】:

        【解决方案4】:

        您显然不能将对象强制转换为它未实现的接口。

        但是,您可以做的(如果从UrlManagementServiceClient 实例中为每个接口实现所有方法有意义的话)是将您的UrlManagementServiceClient 包装 在一个对象中实现你需要的接口。

        这称为Decorator pattern(而不是代理)。代理通常“看起来”是底层对象,而在这种情况下,您正在添加您的客户端没有的功能。

        换句话说,你需要一个新的类:

        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
        }
        

        这允许您重用客户端的实现,并在其之上添加额外的功能。

        【讨论】:

        • 试过了,但是在 ICommunicationObject 和 IUrlManagementService 上要实现很多东西,而且变得一团糟。我采用了另一种方法。
        【解决方案5】:

        为了解决这个问题,我只是扩展了该类并在其上声明了聚合接口:

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

        然后我使用UrlManagementProxy 而不是UrlManagementServiceClient

        我只需要通过我需要的构造函数。其余的都是自动处理的。同样这样我就不需要修改UrlManagementServiceClient,所以我可以重新生成它,一切仍然可以工作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-14
          • 1970-01-01
          • 2018-09-09
          • 1970-01-01
          • 1970-01-01
          • 2023-04-10
          相关资源
          最近更新 更多