Partager via


Procédure : configurer la synchronisation multicouche

Cette rubrique vous indique comment configurer la synchronisation multicouche pour Sync Framework. Les exemples de cette rubrique reposent sur les types Sync Framework suivants :

Pour plus d'informations sur le mode d'exécution d'un exemple de code, consultez la section « Exemples d'application dans les rubriques de procédures » dans Programmation des tâches courantes de synchronisation client et serveur.

Présentation de la synchronisation multicouche

Dans une architecture de synchronisation multicouche, les composants de synchronisation sont répartis sur plusieurs couches, comme le montre l'illustration suivante.

Topologie de synchronisation sur plusieurs couches

Dans une architecture à deux couches, tous les composants résident sur le client et celui-ci communique directement avec le serveur. Dans une architecture multicouche, le fournisseur de synchronisation serveur réside sur le serveur ou une autre couche, et la communication entre les couches est gérée par l'objet ServerSyncProviderProxy et un service, tel que le service WCF (Windows Communication Foundation). L'une des forces de Sync Framework est la facilité avec laquelle vous pouvez déplacer du code entre une architecture à deux couches et une architecture multicouche. Si le code est factorisé convenablement, après avoir créé un service et ajouté un proxy, une seule petite modification doit être apportée au code de l'agent de synchronisation. Les fournisseurs de synchronisation client et serveur ne doivent pas être modifiés.

Exemple

Les exemples de code suivants illustrent les principaux composants qui interviennent dans une architecture multicouche. D'autres composants WCF sont obligatoires. Ces composants sont générés automatiquement si vous utilisez Visual Studio 2008. Pour plus d'informations, consultez la documentation Visual Studio.

Éléments clés de l'API

Cette section fournit des exemples de code qui illustrent les points communs entre la synchronisation à deux couches et la synchronisation multicouche, et désignent les éléments clés de l'API à utiliser lors de la configuration de la synchronisation multicouche. L'exemple de code suivant provient d'une classe qui dérive de SyncAgent. Pour la synchronisation à deux couches, les fournisseurs client et serveur sont tous deux référencés directement dans l'agent de synchronisation en tant que fournisseurs local et distant.

this.LocalProvider = new SampleClientSyncProvider();

this.RemoteProvider = new SampleServerSyncProvider();
Me.LocalProvider = New SampleClientSyncProvider()

Me.RemoteProvider = New SampleServerSyncProvider()

L'exemple de code suivant référence directement le fournisseur client, comme dans l'exemple à deux couches. Toutefois, le fournisseur distant désigne à présent un proxy au lieu de référencer directement le fournisseur serveur. Le proxy est créé en passant une référence à un service WCF.

this.LocalProvider = new SampleClientSyncProvider();

ServiceReference.ServiceForSyncClient serviceProxy = new ServiceReference.ServiceForSyncClient();
this.RemoteProvider = new ServerSyncProviderProxy(serviceProxy);
Me.LocalProvider = New SampleClientSyncProvider()

Dim serviceProxy As New ServiceReference.ServiceForSyncClient()
Me.RemoteProvider = New ServerSyncProviderProxy(serviceProxy)

Les exemples de code suivants créent des fournisseurs client et serveur. Ce code est le même, que l'architecture utilisée soit à deux couches ou multicouche.

public class SampleClientSyncProvider : SqlCeClientSyncProvider
{

    public SampleClientSyncProvider()
    {
        //Specify a connection string for the sample client database.
        Utility util = new Utility();
        this.ConnectionString = util.ClientConnString;
    }
}
public class SampleServerSyncProvider : DbServerSyncProvider
{
    public SampleServerSyncProvider()
    {
        //Create a connection to the sample server database.
        Utility util = new Utility();
        SqlConnection serverConn = new SqlConnection(util.ServerConnString);
        this.Connection = serverConn;

        //Create a command to retrieve a new anchor value from
        //the server.
        SqlCommand selectNewAnchorCommand = new SqlCommand();
        string newAnchorVariable = "@" + SyncSession.SyncNewReceivedAnchor;
        selectNewAnchorCommand.CommandText = "SELECT " + newAnchorVariable + " = min_active_rowversion() - 1";                                                         
        selectNewAnchorCommand.Parameters.Add(newAnchorVariable, SqlDbType.Timestamp);
        selectNewAnchorCommand.Parameters[newAnchorVariable].Direction = ParameterDirection.Output;
        selectNewAnchorCommand.Connection = serverConn;
        this.SelectNewAnchorCommand = selectNewAnchorCommand;

        //Create a SyncAdapter for the Customer table manually, or
        //by using the SqlSyncAdapterBuilder as in the following
        //code.
        SqlSyncAdapterBuilder customerBuilder = new SqlSyncAdapterBuilder(serverConn);

        customerBuilder.TableName = "Sales.Customer";
        customerBuilder.TombstoneTableName = customerBuilder.TableName + "_Tombstone";
        customerBuilder.SyncDirection = SyncDirection.DownloadOnly;
        customerBuilder.CreationTrackingColumn = "InsertTimestamp";
        customerBuilder.UpdateTrackingColumn = "UpdateTimestamp";
        customerBuilder.DeletionTrackingColumn = "DeleteTimestamp";
        
        SyncAdapter customerSyncAdapter = customerBuilder.ToSyncAdapter();
        customerSyncAdapter.TableName = "Customer";
        this.SyncAdapters.Add(customerSyncAdapter);
    }
}
Public Class SampleClientSyncProvider
    Inherits SqlCeClientSyncProvider

    Public Sub New()
        'Specify a connection string for the sample client database.
        Dim util As New Utility()
        Me.ConnectionString = util.ClientConnString

    End Sub
End Class
Public Class SampleServerSyncProvider
    Inherits DbServerSyncProvider

    Public Sub New()
        'Create a connection to the sample server database.
        Dim util As New Utility()
        Dim serverConn As New SqlConnection(util.ServerConnString)
        Me.Connection = serverConn

        'Create a command to retrieve a new anchor value from
        'the server.
        Dim selectNewAnchorCommand As New SqlCommand()
        Dim newAnchorVariable As String = "@" + SyncSession.SyncNewReceivedAnchor
        selectNewAnchorCommand.CommandText = "SELECT " + newAnchorVariable + " = min_active_rowversion()  1"
        selectNewAnchorCommand.Parameters.Add(newAnchorVariable, SqlDbType.Timestamp)
        selectNewAnchorCommand.Parameters(newAnchorVariable).Direction = ParameterDirection.Output
        selectNewAnchorCommand.Connection = serverConn
        Me.SelectNewAnchorCommand = selectNewAnchorCommand

        'Create a SyncAdapter for the Customer table manually, or
        'by using the SqlSyncAdapterBuilder as in the following
        'code.
        Dim customerBuilder As New SqlSyncAdapterBuilder(serverConn)

        customerBuilder.TableName = "Sales.Customer"
        customerBuilder.TombstoneTableName = customerBuilder.TableName + "_Tombstone"
        customerBuilder.SyncDirection = SyncDirection.DownloadOnly
        customerBuilder.CreationTrackingColumn = "InsertTimestamp"
        customerBuilder.UpdateTrackingColumn = "UpdateTimestamp"
        customerBuilder.DeletionTrackingColumn = "DeleteTimestamp"

        Dim customerSyncAdapter As SyncAdapter = customerBuilder.ToSyncAdapter()
        customerSyncAdapter.TableName = "Customer"
        Me.SyncAdapters.Add(customerSyncAdapter)

    End Sub
End Class

L'exemple de code suivant crée une interface que le service implémente. L'interface comprend les quatre méthodes clés du fournisseur serveur.

[ServiceContract]
public interface IServiceForSync
{
    [OperationContract()]
    SyncContext ApplyChanges(SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession);

    [OperationContract()]
    SyncContext GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession);

    [OperationContract()]
    SyncSchema GetSchema(Collection<string> tableNames, SyncSession syncSession);

    [OperationContract()]
    SyncServerInfo GetServerInfo(SyncSession syncSession);
}
<ServiceContract()> _
Public Interface IServiceForSync
    <OperationContract()> _
    Function ApplyChanges(ByVal groupMetadata As SyncGroupMetadata, ByVal dataSet As DataSet, ByVal syncSession As SyncSession) As SyncContext

    <OperationContract()> _
    Function GetChanges(ByVal groupMetadata As SyncGroupMetadata, ByVal syncSession As SyncSession) As SyncContext

    <OperationContract()> _
    Function GetSchema(ByVal tableNames As Collection(Of String), ByVal syncSession As SyncSession) As SyncSchema

    <OperationContract()> _
    Function GetServerInfo(ByVal syncSession As SyncSession) As SyncServerInfo
End Interface

L'exemple de code suivant crée un service. Ce service implémente l'interface créée dans l'exemple de code précédent et référence le fournisseur serveur.

public class ServiceForSync : IServiceForSync
{

    private SampleServerSyncProvider _serverSyncProvider;

    public ServiceForSync()
    {
         this._serverSyncProvider = new SampleServerSyncProvider();
    }
    
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public virtual SyncContext ApplyChanges(SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession) {
        return this._serverSyncProvider.ApplyChanges(groupMetadata, dataSet, syncSession);
    }
    
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public virtual SyncContext GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession) {
        return this._serverSyncProvider.GetChanges(groupMetadata, syncSession);
    }
    
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public virtual SyncSchema GetSchema(Collection<string> tableNames, SyncSession syncSession) {
        return this._serverSyncProvider.GetSchema(tableNames, syncSession);
    }
    
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public virtual SyncServerInfo GetServerInfo(SyncSession syncSession) {
        return this._serverSyncProvider.GetServerInfo(syncSession);
    }       
}
Public Class ServiceForSync
    Implements IServiceForSync

    Private _serverSyncProvider As SampleServerSyncProvider


    Public Sub New()
        Me._serverSyncProvider = New SampleServerSyncProvider()
    End Sub


    <System.Diagnostics.DebuggerNonUserCodeAttribute()> _
    Public Overridable Function ApplyChanges(ByVal groupMetadata As SyncGroupMetadata, ByVal dataSet As DataSet, ByVal syncSession As SyncSession) As SyncContext
        Return Me._serverSyncProvider.ApplyChanges(groupMetadata, dataSet, syncSession)
    End Function


    <System.Diagnostics.DebuggerNonUserCodeAttribute()> _
    Public Overridable Function GetChanges(ByVal groupMetadata As SyncGroupMetadata, ByVal syncSession As SyncSession) As SyncContext
        Return Me._serverSyncProvider.GetChanges(groupMetadata, syncSession)

    End Function


    <System.Diagnostics.DebuggerNonUserCodeAttribute()> _
    Public Overridable Function GetSchema(ByVal tableNames As Collection(Of String), ByVal syncSession As SyncSession) As SyncSchema
        Return Me._serverSyncProvider.GetSchema(tableNames, syncSession)
    End Function


    <System.Diagnostics.DebuggerNonUserCodeAttribute()> _
    Public Overridable Function GetServerInfo(ByVal syncSession As SyncSession) As SyncServerInfo
        Return Me._serverSyncProvider.GetServerInfo(syncSession)
    End Function
End Class

Voir aussi

Concepts

Programmation des tâches courantes de synchronisation client et serveur