다음을 통해 공유


공급자 간의 데이터 변환

많은 응용 프로그램에서 모든 공급자는 정확하게 같은 종류의 데이터를 같은 형식으로 동기화합니다. 예를 들어 몇몇 데이터베이스 동기화 공급자는 ADO.NET 데이터 집합의 테이블 집합에 대해 데이터를 동기화하고 전송할 수 있습니다. 그러나 데이터 형식은 경우에 따라 달라질 수 있습니다. 연락처를 동기화하는 응용 프로그램을 생각해 보면 응용 프로그램에서 두 명의 다른 개발자가 작성한 사용자 지정 공급자를 사용할 경우 이러한 공급자에 필요한 데이터가 다음과 같은 두 가지 측면에서 차이가 날 수 있습니다.

  • 공급자 A는 바이트 스트림으로 데이터를 전송하는 반면 공급자 B는 XML 스트림으로 데이터를 전송합니다.

  • 공급자 A의 데이터는 FirstName, LastName 및 PhoneNumber라는 세 필드로 구성되고, 공급자 B의 데이터는 FirstName 및 LastName을 포함하지만 PhoneNumber가 PhoneNumber와 AreaCode로 나눠집니다.

이 시나리오를 처리하려면 Sync Framework에서 데이터를 각 공급자에 필요한 형식으로 변환하는 인터페이스를 구현해야 합니다. 이 경우 두 가지 변환을 수행하는 변환기를 작성할 수 있습니다. 첫 번째는 바이트 스트림 입력을 XML 출력으로 변환하는 것이고, 두 번째는 XML 입력을 바이트 스트림 출력으로 변환하는 것입니다. Sync Framework에서는 두 공급자 모두에게 변환기를 지정하지 않아도 됩니다. 구현하는 데이터 변환 코드는 동기화 세션에서 호출되어 변경 내용 적용 프로세스 동안 데이터 변환이 대상 공급자에 인식되지 않습니다.

또한 다양한 데이터 형식을 가진 많은 수의 공급자에 대해 서로 데이터를 동기화해야 하는 시나리오를 생각해 보면 가능한 방법 중 하나는 각 공급자 쌍에 대한 변환기를 작성하는 것이지만 관리하기 어려워질 수 있습니다. 더 좋은 방법은 각 공급자에 대해 데이터와 중간 형식 간에 변환하는 변환기를 작성하는 것입니다. 이 경우 두 가지 데이터 변환이 수행됩니다. 하나는 원본 공급자에서 중간 형식으로 변환하는 것이고, 다른 하나는 중간 형식에서 대상 공급자 형식으로 변환하는 것입니다.

다음 표에서는 데이터 변환에 대해 Sync Framework에서 제공되는 인터페이스 및 속성을 보여 줍니다.

관리 코드 비관리 코드

SyncDataConverter

ISyncDataConverter 인터페이스

LocalDataConverter

ISyncDataConversionControl 인터페이스

RemoteDataConverter

 

다음 방법을 사용하여 각 공급자의 데이터를 변환합니다.

  1. 각 공급자의 변환기를 구현합니다.

    • 관리 코드 두 필수 SyncDataConverter 메서드인 ConvertDataFromProviderFormatConvertDataToProviderFormat을 구현합니다.

    • 비관리 코드 두 필수 ISyncDataConverter 메서드인 ConvertDataFromProviderFormatConvertDataToProviderFormat을 구현합니다.

  2. 동기화 세션 중에 사용할 변환기를 지정합니다.

    • 관리 코드 구현한 변환기를 두 SyncOrchestrator 속성인 LocalDataConverterRemoteDataConverter로 지정합니다.

    • 비관리 코드 구현한 변환기를 두 ISyncDataConversionControl 메서드인 SetSourceDataConverterSetDestinationDataConverter에 지정합니다.

대부분의 경우 사용할 수 있는 네 가지 변환 메서드 중 두 개만 구현하고 동기화 세션에 지정하게 됩니다. 데이터 검색자 변환과 관련된 두 메서드는 사용하는 데이터 검색자가 IChangeDataRetriever(관리 코드의 경우) 또는 IAsynchronousDataRetriever 또는 ISynchronousDataRetriever(비관리 코드의 경우)의 구현이 아닌 경우에만 필요합니다. 데이터를 중간 상태로 변환하는 상황에서 Sync Framework 데이터 검색자 인터페이스의 구현을 사용해야 합니다.

Sync Framework에서는 하나 또는 두 공급자가 관리되지 않는 경우 관리되는 응용 프로그램에서 데이터 변환을 지원합니다. 변환 프로세스는 항상 관리되는 개체에서 처리된다는 점에 유의하십시오. 이로 인해 응용 프로그램이 관리되지 않으면 동기화 시간이 오래 걸릴 수 있습니다.

코드 예

다음 코드 예제는 데이터 변환이 필요한 두 공급자를 동기화하는 방법을 보여줍니다. Execute 메서드에서 코드는 먼저 동기화될 공급자를 인스턴스화한 다음 입력 및 출력 형식을 허용하는 데이터 변환 클래스의 두 인스턴스를 인스턴스화합니다. 이 예제에서 ConvertDataFromProviderFormatConvertDataToProviderFormat 메서드는 데이터를 변경하지 않고 반환하지만 실제 응용 프로그램에서는 입력 형식을 적절한 출력 형식으로 변환해야 합니다.

public class SampleConversion
{
    public void Execute()
    {

        SyncOrchestrator orchestrator = new SyncOrchestrator();
        orchestrator.Direction = SyncDirectionOrder.Upload;
        orchestrator.LocalProvider = new SampleSyncProvider(localStore);
        orchestrator.RemoteProvider = new SampleSyncProvider(remoteStore);

        DataConverter<DataObject1, DataObject2> localConverter = new DataConverter<DataObject1, DataObject2>();

        DataConverter<DataObject2, DataObject3> remoteConverter = new DataConverter<DataObject2, DataObject3>();

        orchestrator.LocalDataConverter = localConverter;
        orchestrator.RemoteDataConverter = remoteConverter;

        orchestrator.Synchronize();
    }

    string localStore;
    string remoteStore;
}

public class DataConverter<SourceType, DestType> : SyncDataConverter
    where SourceType : IDataObject, new()
    where DestType : IDataObject, new()
{
    public DataConverter()
    {
    }

    public override object ConvertDataFromProviderFormat(LoadChangeContext loadChangeContext, object itemData)
    {
        SourceType dataObj = (SourceType)itemData;

        DestType returnData = new DestType();
        returnData.Data = dataObj.Data;

        return returnData;
    }

    public override object ConvertDataToProviderFormat(LoadChangeContext loadChangeContext, object itemData)
    {
        DestType dataObj = (DestType)itemData;

        SourceType returnData = new SourceType();
        returnData.Data = dataObj.Data;

        return returnData;
    }

    Type sourceType;
    Type destType;
}
Public Class SampleConversion
    Public Sub Execute()

        Dim orchestrator As New SyncOrchestrator()
        orchestrator.Direction = SyncDirectionOrder.Upload
        orchestrator.LocalProvider = New SampleSyncProvider(localStore)
        orchestrator.RemoteProvider = New SampleSyncProvider(remoteStore)

        Dim localConverter As New DataConverter(Of DataObject1, DataObject2)()

        Dim remoteConverter As New DataConverter(Of DataObject2, DataObject3)()

        orchestrator.LocalDataConverter = localConverter
        orchestrator.RemoteDataConverter = remoteConverter

        orchestrator.Synchronize()
    End Sub

    Private localStore As String
    Private remoteStore As String
End Class

Public Class DataConverter(Of SourceType As {IDataObject, New}, DestType As {IDataObject, New})
    Inherits SyncDataConverter
    Public Sub New()
    End Sub

    Public Overloads Overrides Function ConvertDataFromProviderFormat(ByVal loadChangeContext As LoadChangeContext, ByVal itemData As Object) As Object
        Dim dataObj As SourceType = DirectCast(itemData, SourceType)

        Dim returnData As New DestType()
        returnData.Data = dataObj.Data

        Return returnData
    End Function

    Public Overloads Overrides Function ConvertDataToProviderFormat(ByVal loadChangeContext As LoadChangeContext, ByVal itemData As Object) As Object
        Dim dataObj As DestType = DirectCast(itemData, DestType)

        Dim returnData As New SourceType()
        returnData.Data = dataObj.Data

        Return returnData
    End Function

    Private sourceType As Type
    Private destType As Type
End Class

다음 코드 예제에서는 데이터 검색 변환 메서드인 TryConvertDataRetrieverFromProviderFormatTryConvertDataRetrieverToProviderFormat을 정의합니다. 두 메서드 모두 데이터 검색자와 변경 내용의 목록을 허용합니다. 데이터 검색자 변환을 수행하기 위해 IChangeDataRetriever를 상속하는 ConvertedDataRetriever 샘플 클래스를 인스턴스화합니다.

public override bool TryConvertDataRetrieverFromProviderFormat(
    object dataRetrieverIn,
    IEnumerable<ItemChange> changes,
    out object dataRetrieverOut)
{
    dataRetrieverOut = new ConvertedDataRetriever<SourceType, DestType>(dataRetrieverIn);
    return true;
}

public override bool TryConvertDataRetrieverToProviderFormat(
    object dataRetrieverIn,
    IEnumerable<ItemChange> changes,
    out object dataRetrieverOut)
{
    dataRetrieverOut = new ConvertedDataRetriever<DestType, SourceType>(dataRetrieverIn);
    return true;
}
Public Overloads Overrides Function TryConvertDataRetrieverFromProviderFormat(ByVal dataRetrieverIn As Object, ByVal changes As IEnumerable(Of ItemChange), ByRef dataRetrieverOut As Object) As Boolean
    dataRetrieverOut = New ConvertedDataRetriever(Of SourceType, DestType)(dataRetrieverIn)
    Return True
End Function

Public Overloads Overrides Function TryConvertDataRetrieverToProviderFormat(ByVal dataRetrieverIn As Object, ByVal changes As IEnumerable(Of ItemChange), ByRef dataRetrieverOut As Object) As Boolean
    dataRetrieverOut = New ConvertedDataRetriever(Of DestType, SourceType)(dataRetrieverIn)
    Return True
End Function

다음 코드 예제에서는 ConvertedDataRetriever 클래스를 만들고 LoadChangeData 메서드 및 IdFormats 속성을 정의합니다. 데이터 검색자를 변환할 때 데이터 변환에 필요한 모든 코드가 LoadChangeData 메서드에 포함되어 있거나 호출되어야 합니다.

public class ConvertedDataRetriever<SourceType, DestType> : IChangeDataRetriever
    where SourceType : IDataObject, new()
    where DestType : IDataObject, new()
{
    public ConvertedDataRetriever(object dataRetriever)
    {
        this.dataRetriever = dataRetriever;
    }

    public SyncIdFormatGroup IdFormats
    {
        get
        {
            return ((IChangeDataRetriever)dataRetriever).IdFormats;
        }
    }

    public object LoadChangeData(LoadChangeContext loadChangeContext)
    {
        IChangeDataRetriever iRetriever = (IChangeDataRetriever)dataRetriever;

        object tempData = iRetriever.LoadChangeData(loadChangeContext);

        if (tempData != null)
        {
            return ConvertData(tempData);
        }

        return null;
    }

    private object ConvertData(object itemData)
    {
        SourceType dataObj = (SourceType)itemData;

        DestType returnData = new DestType();
        returnData.Data = dataObj.Data;

        return returnData;
    }

    object dataRetriever;
}
Public Class ConvertedDataRetriever(Of SourceType As {IDataObject, New}, DestType As {IDataObject, New})
    Implements IChangeDataRetriever
    Public Sub New(ByVal dataRetriever As Object)
        Me.dataRetriever = dataRetriever
    End Sub

    Public ReadOnly Property IdFormats() As SyncIdFormatGroup
        Get
            Return DirectCast(dataRetriever, IChangeDataRetriever).IdFormats
        End Get
    End Property

    Public Function LoadChangeData(ByVal loadChangeContext As LoadChangeContext) As Object
        Dim iRetriever As IChangeDataRetriever = DirectCast(dataRetriever, IChangeDataRetriever)

        Dim tempData As Object = iRetriever.LoadChangeData(loadChangeContext)

        If tempData IsNot Nothing Then
            Return ConvertData(tempData)
        End If

        Return Nothing
    End Function

    Private Function ConvertData(ByVal itemData As Object) As Object
        Dim dataObj As SourceType = DirectCast(itemData, SourceType)

        Dim returnData As New DestType()
        returnData.Data = dataObj.Data

        Return returnData
    End Function

    Private dataRetriever As Object
End Class

참고 항목

개념

다른 공급자의 데이터 통합