Skip to main content
 首页 » 编程设计

c#之.NET Architectural issue : 2 Web Services, 如何更改在运行时使用哪一个

2024年02月03日29lovecherry

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

现在我们的应用程序使用对 ReportService 的 Web 引用并使用该服务公开的各种对象。 ReportService2006 具有完全相同的对象,但它们显然位于不同的命名空间中,例如我有 2 个 Web 引用 - 每个服务 1 个,因此有一个对象 MyApplication.ReportService.CatalogItem 和另一个 MyApplication.ReportService2006.CatalogItem。

我尝试使用依赖注入(inject)从我们的应用程序中抽象出服务,并结合工厂模式来确定要实例化我的接口(interface)的哪个实现。这是我的界面。我已将其简化为仅包含此应用程序所需的调用。

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); 
    } 
} 

所以我有 2 个实现,每个实现都实例化了不同的 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 */ 
    } 
  } 

所以计划是我可以在运行时将这些注入(inject)到我的 ServiceWrapper 中。但是 - 如果您注意到该接口(interface)与 ReportService 相关联,并且某些方法返回来自 Web 引用的对象,例如目录项。因此我的项目不会构建,因为我的 ReportService2006 实现引用了来自不同命名空间的 CatalogItem。

有什么想法吗?我这样做的方向完全错误吗?

请您参考如下方法:

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

WCF 确实通过服务契约解决了这些问题中的大部分,如果我之前的建议被证明太难以管理,您可以考虑迁移到 WCF 解决方案。