문제

Reporting Services 및 SharePoint와 협력하고 있으며보고 서비스를 활용하는 응용 프로그램이 있지만 고객은 신청서를 SharePoint에 통합하기를 원합니다. 현재 우리는 ReportsErvice.asmx 웹 서비스와 밀접하게 결합되어 작업을 수행하기위한 다양한 방법을 노출시킵니다. 보고서 서비스에는 보고서 서버가 다르게 작동하며 SharePoint가 보고서를 관리하는 데 사용됩니다. SharePoint는 거의 정확히 동일한 reportservice2006.asmx라는 새로운 웹 서비스를 추가합니다.

이제 응용 프로그램은 Reportservice에 대한 웹 참조를 사용하고 서비스에서 노출 된 다양한 객체를 사용합니다. ReportsErvice2006은 정확히 동일한 객체를 가지고 있지만 분명히 다른 네임 스페이스에 있습니다. 예를 들어 각 서비스에 1 개의 웹 참조가 있습니다. 따라서 객체 myApplication.reportService.catalogitem과 다른 myApplication.ReportService2006.catalogitem이 있습니다.

나는 의존성 주입을 사용하여 공장 패턴과 결합 된 응용 프로그램에서 서비스를 부적합 시키려고 노력하여 인스턴스화 할 인터페이스의 구현을 결정했습니다. 그녀는 내 인터페이스입니다. 이 응용 프로그램에 필요한 통화 만 포함하도록 단순화했습니다.

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

따라서 다른 웹 서비스를 인스턴스화하는 각각의 두 가지 구현이 있습니다.

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 */
    }
  }

따라서 계획은 실행 시간에 서비스 표시에 주입 할 수 있다는 것입니다. 그러나 인터페이스가 reportservice에 묶여 있고 일부 메소드가 웹 참조, 즉 Catalogitem에서 나온 객체를 반환하는 것을 알 수 있습니다. 따라서 ReportsErvice2006의 구현이 다른 네임 스페이스에서 카탈로그를 참조하기 때문에 내 프로젝트가 구축되지 않습니다.

어떤 아이디어? 나는 이것으로 완전히 잘못된 방향으로 가고 있습니까?

도움이 되었습니까?

해결책

가장 강력한 솔루션은 카탈로그 설정 인터페이스를 만들고 각 웹 서비스에 대한 포장지를 만들고 공장 뒤에 모든 것을 숨기는 것입니다. 공장에는 "올바른"웹 서비스를 호출하는 논리가 포함되어 있으며 인터페이스를 사용하려면 클라이언트 코드를 변경해야하지만 더 나은 변화입니다.

WCF는 서비스 계약으로 이러한 문제의 대부분을 해결하며, 이전 조언이 너무 관리 할 수없는 것으로 판명되면 WCF 솔루션으로 마이그레이션을 고려할 수 있습니다.

다른 팁

나는 당신 이이 상황을 위해 올바른 방향으로 향하고 있다고 생각합니다. 집으로 운전하기 위해 더 많은 일을 할 것입니다. 반사 또는 동적 방법을 사용하여 두 버전의 클래스를 모두 랩핑 할 수있는 프록시 클래스를 만들 것입니다. 또한 사람들이 원격 네임 스페이스의 프록시 클래스를 사용하여 런타임시 메소드 호출을 가로 채고 올바른 위치로 안내하는 것을 보았습니다.이 방법으로 손으로 코딩하는 대신 요청시 동적 메소드를 만들 수 있습니다. 객체의 인터페이스와 일치하는 인터페이스입니다.

Either add the reference it needs or build wrappers for CatalogItem and the rest of the specific classes. I'd build the wrappers, the interface should be able to stand on its own without referencing any particular implementation.

If the Web Services reside in different namespaces, then there is no trivial solution (eg. something as simple as changing the URL). You seem to be on the right track with abstraction though.

If you're feeling adventurous though, you can modify the generated Web Service classes yourself (the "reference.cs" files), and then manually add them to your project. First create a common Interface, then modify the first lines in the file like such:

public partial class MyWebService : SoapHttpClientProtocol, IMyWebService

Then you use this to call the code:

IMyWebService webService = new MyWebService();  // Or you can use a Factory

In VS2008, if I try to add a ServiceReference to a webservice, I see an advanced button. When clicking it, there is an option to "re-use types".

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top