代码之家  ›  专栏  ›  技术社区  ›  Rob Stevenson-Leggett

.NET体系结构问题:2 Web服务,如何更改运行时使用的服务?

  •  1
  • Rob Stevenson-Leggett  · 技术社区  · 16 年前

    我正在使用Reporting Services和Sharepoint,我有一个利用Reporting Services的应用程序,但是客户希望我们的应用程序集成到Sharepoint中。目前,我们与ReportService.asmx webservice紧密耦合,它公开了执行操作的各种方法。Reporting Services具有一种称为“Sharepoint集成模式”的功能,如果启用此功能,报表服务器的工作方式将不同,并且Sharepoint将用于管理报表。Sharepoint添加了一个名为ReportService2006.asmx的新web服务,该服务几乎完全相同。

    我曾尝试使用依赖注入将服务从应用程序中分离出来,并使用工厂模式来确定要实例化的接口实现。这是我的界面。我已将其简化为只包含此应用程序所需的调用。

    using System;
    using NetworkUserEncrypt.ReportService;
    
    namespace MyApplication.Service
    {
        public interface IReportingService
        {
            CatalogItem CreateDataSource(string DataSource, string Parent, bool Overwrite, DataSourceDefinition Definition, Property[] Properties);
    
            void DeleteItem(string Item);
    
            DataSourceDefinition GetDataSourceContents(string DataSource);
    
            byte[] GetReportDefinition(string Report);
    
            CatalogItem[] ListChildren(string Item);
        }
    }
    

    因此,我有两个实现,每个实现实例化一个不同的web服务,例如:

    namespace MyApp.Service.Implementation
    {
        class ReportingServiceImpl : IReportingService
        {
            ReportingService _service = null;
    
            public ReportingServiceImpl()
            {
                ReportingService _service = new ReportingService();
            }
    
            /* SNIP */
        }
      }
    

    namespace MyApp.Service.Implementation
    {
        class ReportingService2006Impl : IReportingService
        {
            ReportingService2006 _service = null;
    
            public ReportingService2006Impl()
            {
                ReportingService2006 _service = new ReportingService2006();
            }
    
            /* SNIP */
        }
      }
    

    5 回复  |  直到 15 年前
        1
  •  1
  •   scmccart    16 年前

    我认为你在这种情况下朝着正确的方向前进,只是需要做更多的工作才能把它带回家。我将创建一些代理类,它们可以使用反射或动态方法包装这两个版本的类。我还看到人们使用远程处理命名空间中的代理类在运行时截获方法调用并将它们定向到正确的位置,这样您就可以根据需要创建动态方法,而不是手工编写它们,您真正需要的是一个匹配对象接口的接口。

        2
  •  1
  •   Mauricio Scheffer    16 年前

    添加所需的引用或为CatalogItem和其他特定类构建包装器。如果我构建包装器,接口应该能够独立运行,而无需引用任何特定的实现。

        3
  •  1
  •   ilitirit    16 年前

    如果Web服务驻留在不同的名称空间中,那么就没有简单的解决方案(例如更改URL这样简单的事情)。不过,你在抽象方面似乎走对了方向。

    public partial class MyWebService : SoapHttpClientProtocol, IMyWebService
    

    然后,使用此函数调用代码:

    IMyWebService webService = new MyWebService();  // Or you can use a Factory
    
        4
  •  1
  •   Amy B    16 年前

        5
  •  1
  •   Phil Bennett    16 年前

    最健壮的解决方案是创建CatalogItem接口,为每个web服务创建包装器,并将整个过程隐藏在工厂后面。工厂将包含调用“正确”web服务的逻辑,并且必须更改客户端代码才能使用该接口,但这是一个更好的更改。