Como configurar a sincronização de n camadas
Este tópico mostra como configurar a sincronização de N camadas para Sync Framework. Os exemplos deste tópico focalizam os seguintes tipos do Sync Framework:
Para obter informações sobre como executar o código de amostra, consulte "Exemplo de aplicativos nos tópicos de instruções" em Programando tarefas comuns de sincronização do cliente e do servidor.
Noções básicas sobre sincronização de N camadas
Em uma arquitetura de sincronização de N camadas, os componentes de sincronização se espalham por várias camadas, como mostra a ilustração a seguir.
Em uma arquitetura de duas camadas, todos os componentes residem no cliente, e este se comunica diretamente com o servidor. Em uma arquitetura de N camadas, o provedor de sincronização do servidor reside no servidor ou em outra camada, e a comunicação entre as camadas é tratada pelo objeto ServerSyncProviderProxy e um serviço, como um serviço Windows Communication Foundation (WCF). Um dos pontos fortes do Sync Framework é a facilidade com a qual é possível mover código de uma arquitetura de duas camadas para uma de N camadas. Se o código for fatorado de forma adequada, depois que você criar um serviço e adicionar um proxy, será necessária apenas uma pequena alteração no código do agente de sincronização. Os provedores de sincronização de cliente e servidor não precisam ser alterados.
Exemplo
Os exemplos de código a seguir mostram os principais componentes envolvidos em uma arquitetura de N camadas. São necessários componentes WCF adicionais. Esses componentes serão gerados se você usar o Visual Studio 2008. Para obter mais informações, consulte a documentação do Visual Studio.
Partes principais da API
Esta seção fornece exemplos de código que demonstram as semelhanças entre as sincronizações de duas e N camadas, além de destacar as partes principais da API usadas quando você está configurando a sincronização de N camadas. O exemplo de código a seguir é de uma classe derivada de SyncAgent. Para a sincronização de duas camadas, o provedor do cliente e o provedor do servidor são referenciados diretamente no agente de sincronização como provedores local e remoto.
this.LocalProvider = new SampleClientSyncProvider();
this.RemoteProvider = new SampleServerSyncProvider();
Me.LocalProvider = New SampleClientSyncProvider()
Me.RemoteProvider = New SampleServerSyncProvider()
O exemplo de código a seguir referencia o provedor do cliente diretamente, como no exemplo de duas camadas. Entretanto, o provedor remoto agora referencia um proxy em vez de referenciar diretamente o provedor do servidor. O proxy é criado passando-se uma referência para um serviço 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)
Os exemplos de código a seguir criam provedores cliente e servidor. Esse código será idêntico se for usada uma arquitetura de duas ou N camadas.
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
O exemplo de código a seguir cria uma interface que o serviço implementa. A interface inclui os quatro métodos principais do provedor do servidor.
[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
O exemplo de código a seguir cria um serviço. Esse serviço implementa a interface que foi criada no exemplo de código anterior e referencia o provedor do servidor.
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
Consulte também
Conceitos
Programando tarefas comuns de sincronização do cliente e do servidor