Como criar um provedor de sincronização gerenciado
Este tópico descreve como usar uma linguagem gerenciada para criar um provedor de sincronização do Sync Framework que sincronize dados de um repositório de dados personalizado.
Este tópico pressupõe uma familiaridade básica com os conceitos de C# e Microsoft .NET Framework.
Os exemplos neste tópico se concentram nas seguintes classes e interfaces do Sync Framework:
Noções básicas sobre provedores de sincronização
Um provedor de sincronização é um componente de software que representa uma réplica durante a sincronização. Isso permite que a réplica sincronize seus dados com outras réplicas. Para que a sincronização ocorra, um aplicativo primeiro cria um objeto SyncOrchestrator, conecta-o a dois objetos SyncProvider e inicia a sincronização. Um dos provedores representa a réplica de origem. Essa réplica fornece metadados para itens alterados por meio do seu método GetChangeBatch e dados de item por meio de um objeto IChangeDataRetriever. O outro provedor representa a réplica de destino. Essa réplica recebe metadados para itens alterados por meio do seu método ProcessChangeBatch e aplica as alterações ao seu repositório de itens usando um objeto NotifyingChangeApplier fornecido pelo Sync Framework junto com seu próprio objeto INotifyingChangeApplierTarget.
Para obter mais informações sobre a função do provedor de sincronização, consulte Implementando um provedor personalizado padrão.
Requisitos de compilação
.NET Framework 2.0 ou posterior.
Referência ao Microsoft.Synchronization.
Referência ao Microsoft.Synchronization.MetadataStorage.
Exemplo
O código de exemplo deste tópico mostra como implementar os métodos básicos de classe e interface necessários para que uma réplica participe de uma comunidade de sincronização do Sync Framework como uma origem e como um destino. A réplica deste exemplo é um arquivo de texto que armazena informações de contato como uma lista de valores separados por vírgula. Os itens a serem sincronizados são os contatos contidos nesse arquivo. Este exemplo também usa um repositório de metadados personalizado implementado por meio da API do serviço de armazenamento de metadados. Para obter informações sobre o serviço de armazenamento de metadados, consulte Sync Framework Metadata Storage Service.
Nos exemplos seguintes, _itemStore
representa um objeto que contém o repositório de itens e o repositório de metadados.
Implementando SyncProvider e IKnowledgeSyncProvider
O ponto de entrada do provedor é a classe SyncProvider. O objetivo dessa classe é funcionar como uma classe base para outras classes de provedor mais avançadas. Este exemplo usa a classe KnowledgeSyncProvider.
Declarando KnowledgeSyncProvider
Adicione KnowledgeSyncProvider à lista de herança de classe.
class ContactsProviderXmlMetadataNoChangeUnits : KnowledgeSyncProvider
Adicione os métodos SyncProvider e KnowledgeSyncProvider à classe.
Propriedade IdFormats
O Sync Framework chama IdFormats nos provedores de origem e de destino quando Synchronize é chamado no objeto SyncOrchestrator. A propriedade IdFormats retorna o esquema de formato de ID usado pelo provedor. O esquema deve ser o mesmo para ambos os provedores. Este exemplo define tamanhos para IDs de item que contêm um SyncGlobalId, IDs de réplica que contêm o caminho absoluto da réplica, e IDs de unidade de alteração que são membros de uma enumeração.
public override SyncIdFormatGroup IdFormats
{
get
{
SyncIdFormatGroup FormatGroup = new SyncIdFormatGroup();
// Item IDs are of SyncGlobalId type, so they are fixed length and contain a ulong prefix plus a Guid.
FormatGroup.ItemIdFormat.IsVariableLength = false;
FormatGroup.ItemIdFormat.Length = (ushort)(sizeof(ulong) + Marshal.SizeOf(typeof(Guid)));
// Replica IDs are the absolute path to the item store, so they are variable length with maximum
// length equal to the maximum length of a path.
FormatGroup.ReplicaIdFormat.IsVariableLength = true;
FormatGroup.ReplicaIdFormat.Length = 260 * sizeof(char);
return FormatGroup;
}
}
Método BeginSession
O Sync Framework chama BeginSession nos provedores de origem e de destino antes de chamar quaisquer outros métodos. Esse método informa a um provedor que ele está ingressando em uma sessão de sincronização e passa para o provedor um objeto que contém informações sobre o estado da sessão. Essa implementação armazenará o objeto de estado de sessão ou irá gerar SyncInvalidOperationException se o provedor já tiver ingressado em uma sessão de sincronização.
public override void BeginSession(SyncProviderPosition position, SyncSessionContext syncSessionContext)
{
// If this object is already in a session, throw an exception.
if (null != _sessionContext)
{
throw new SyncInvalidOperationException();
}
_sessionContext = syncSessionContext;
}
Método GetSyncBatchParameters
O Sync Framework chama GetSyncBatchParameters no provedor de destino. Esse método recupera o número de alterações que o provedor de origem deve incluir em um lote de alterações e obtém o conhecimento atual do provedor de destino. Essa implementação extrai o conhecimento do repositório de metadados e define o tamanho do lote como 10
.
public override void GetSyncBatchParameters(out uint batchSize, out SyncKnowledge knowledge)
{
// Set a batch size of 10.
batchSize = 10;
// Return the current knowledge of the replica.
knowledge = _itemStore.ContactReplicaMetadata.GetKnowledge();
}
O objeto de repositório de metadados retorna o conhecimento atual da réplica usando GetKnowledge. Essa implementação criará um novo objeto SyncKnowledge se a réplica ainda não contiver nenhum conhecimento, e definirá a contagem em escala do conhecimento como a contagem em escala atual da réplica.
public override SyncKnowledge GetKnowledge()
{
// If the replica does not yet contain any knowledge, create a new knowledge object.
if (null == _knowledge)
{
_knowledge = new SyncKnowledge(IdFormats, ReplicaId, _tickCount);
}
// Ensure the tick count of the knowledge is set to the current tick count of the replica.
_knowledge.SetLocalTickCount(_tickCount);
return _knowledge;
}
Método GetChangeBatch
A sessão de sincronização é iniciada efetivamente quando o Sync Framework chama GetChangeBatch no provedor de origem. Esse método recupera um lote de alterações para ser enviado ao provedor de destino e também retorna a interface de recuperador de dados. O Sync Framework usa a interface de recuperador de dados para obter um object que o provedor de destino utiliza para recuperar dados de item de alterações aplicadas à réplica de destino. O Sync Framework chama GetChangeBatch repetidamente, até que o último lote seja enviado. O provedor de origem indica que um lote é o último chamando o método SetLastBatch no objeto de lote de alterações. Essa implementação delega a tarefa de enumeração de alterações ao objeto de repositório de metadados. O objeto de provedor implementa IChangeDataRetriever; portanto, ele é retornado no parâmetro changeDataRetriever
.
public override ChangeBatch GetChangeBatch(uint batchSize, SyncKnowledge destinationKnowledge, out object changeDataRetriever)
{
// Return this object as the IChangeDataRetriever object that is called to retrieve item data.
changeDataRetriever = this;
// Call the metadata store to get a batch of changes.
return _itemStore.ContactReplicaMetadata.GetChangeBatch(batchSize, destinationKnowledge);
}
O objeto de repositório de metadados retorna um lote de alterações usando GetChangeBatch. Essa implementação armazena itens no repositório de metadados como uma lista de objetos ItemMetadata que são ordenados por ID de item. Os itens são enumerados e uma alteração será adicionada a um grupo ordenado no objeto de lote de alterações se a alteração não estiver contida no conhecimento de destino. Quando todos os itens do repositório de metadados estiverem enumerados, SetLastBatch será chamado no lote de alteração.
public override ChangeBatch GetChangeBatch(uint batchSize, SyncKnowledge destinationKnowledge)
{
// The destination knowledge must be converted to be compatible with the source replica
// before it can be used.
SyncKnowledge mappedDestKnowledge = _knowledge.MapRemoteKnowledgeToLocal(destinationKnowledge);
// Create a new change batch, initialized by using the current knowledge of the source replica
// and a new ForgottenKnowledge object.
ChangeBatch changeBatch = new ChangeBatch(IdFormats, GetKnowledge(), new ForgottenKnowledge());
// Start a group of changes in the change batch. The group is ordered by item ID.
// _getChangeBatchCurrent is 0 the first time GetChangeBatch is called, and is used to track the
// position in the metadata store for subsequent calls to GetChangeBatch.
changeBatch.BeginOrderedGroup(_items.Values[_getChangeBatchCurrent].GlobalId);
// itemsAdded is incremented each time a change is added to the change batch. When itemsAdded
// is greater than the requested batch size, enumeration stops and the change batch is returned.
int itemsAdded = 0;
ItemMetadata itemMeta;
// Enumerate items and add a change to the change batch if it is not contained in the
// destination knowledge.
// _items is a SortedList that contains ItemMetadata objects that are ordered by item ID.
for (; itemsAdded <= batchSize && _getChangeBatchCurrent < _items.Count; _getChangeBatchCurrent++)
{
itemMeta = _items.Values[_getChangeBatchCurrent];
ChangeKind kind = (itemMeta.IsDeleted) ? ChangeKind.Deleted : ChangeKind.Update;
ItemChange change = new ItemChange(IdFormats, ReplicaId, itemMeta.GlobalId, kind, itemMeta.CreationVersion,
itemMeta.ChangeVersion);
// If the change is not contained in the destination knowledge, add it to the change batch.
if (!mappedDestKnowledge.Contains(change))
{
changeBatch.AddChange(change);
itemsAdded++;
}
}
// End the group of changes in the change batch. Pass the current source knowledge.
changeBatch.EndOrderedGroup(_items.Values[_getChangeBatchCurrent - 1].GlobalId, _knowledge);
// When all items in the metadata store have been enumerated, set this batch as the
// last batch.
if (_getChangeBatchCurrent == _items.Count)
{
changeBatch.SetLastBatch();
}
return changeBatch;
}
Método ProcessChangeBatch
Depois que o Sync Framework tiver obtido um lote de alterações do provedor de origem chamando seu método GetChangeBatch, o Sync Framework chama ProcessChangeBatch no provedor de destino. Esse método aplica as alterações à réplica de destino. Esse método é chamado uma vez para cada lote de alterações recuperado de GetChangeBatch no provedor de origem. Essa implementação usa o objeto de repositório de metadados para obter informações de versão local de itens do provedor de origem. Ele então cria um objeto NotifyingChangeApplier implementado pelo Sync Framework e chama seu método ApplyChanges.
public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallbacks, SyncSessionStatistics sessionStatistics)
{
// Use the metadata store to get the local versions of changes received from the source provider.
IEnumerable<ItemChange> destVersions = _itemStore.ContactReplicaMetadata.GetLocalVersions(sourceChanges);
// Use a NotifyingChangeApplier object to process the changes. Note that this object is passed as the INotifyingChangeApplierTarget
// object that will be called to apply changes to the item store.
NotifyingChangeApplier changeApplier = new NotifyingChangeApplier(IdFormats);
changeApplier.ApplyChanges(resolutionPolicy, sourceChanges, (IChangeDataRetriever)changeDataRetriever, destVersions,
_itemStore.ContactReplicaMetadata.GetKnowledge(), _itemStore.ContactReplicaMetadata.GetForgottenKnowledge(),
this, _sessionContext, syncCallbacks);
}
O objeto de repositório de metadados retorna informações de versão local dos itens do provedor de origem usando GetLocalVersions. Essa implementação enumera as alterações enviadas no lote de alterações do provedor de origem. Se um item estiver nos metadados de destino, suas informações de versão serão adicionadas a uma lista de alterações que contém as informações de versão. Se um item não existir nos metadados de destino, ele será sinalizado como um item desconhecido na lista de versões local.
public override IEnumerable<ItemChange> GetLocalVersions(ChangeBatch sourceChanges)
{
List<ItemChange> localVersions = new List<ItemChange>();
// Enumerate the source changes and retrieve the destination version for each source change.
foreach (ItemChange srcItem in sourceChanges)
{
ItemChange localVer;
// When the source item exists in the destination metadata store, retrieve the destination version of the item.
if (_items.ContainsKey(srcItem.ItemId))
{
XmlItemMetadata localMeta = _items[srcItem.ItemId];
ChangeKind kind = (localMeta.IsDeleted) ? ChangeKind.Deleted : ChangeKind.Update;
localVer = new ItemChange(IdFormats, ReplicaId, srcItem.ItemId, kind, localMeta.CreationVersion, localMeta.ChangeVersion);
}
// When the source item does not exist in the destination metadata store, create a new change with unknown
// version information.
else
{
localVer = new ItemChange(IdFormats, ReplicaId, srcItem.ItemId, ChangeKind.UnknownItem, SyncVersion.UnknownVersion, SyncVersion.UnknownVersion);
}
localVersions.Add(localVer);
}
return localVersions;
}
Método EndSession
Depois que o provedor de origem envia o último lote e o provedor de destino aplica as alterações ao seu repositório de dados, o Sync Framework chama EndSession nos provedores de origem e de destino. Esse método informa a um provedor que ele está saindo de uma sessão de sincronização e deve liberar os recursos associados à sessão. Essa implementação libera o objeto de estado de sessão que foi armazenado na chamada BeginSession ou gera SyncInvalidOperationException se o provedor não ingressou previamente em uma sessão de sincronização.
public override void EndSession(SyncSessionContext syncSessionContext)
{
// If this object is not in a session, throw an exception.
if (null == _sessionContext)
{
throw new SyncInvalidOperationException();
}
_sessionContext = null;
}
Métodos não implementados
Os métodos a seguir não são necessários, pois este exemplo nunca remove itens marcados como excluídos no repositório de metadados. Estes métodos podem gerar NotImplementedException:
Implementando INotifyingChangeApplierTarget
Essa interface é fornecida para o Sync Framework quando o provedor de destino chama o método ApplyChanges, normalmente no método ProcessChangeBatch. INotifyingChangeApplierTarget contém métodos chamados durante a aplicação de alterações. Esses métodos só são chamados no provedor de destino.
Declarando INotifyingChangeApplierTarget
Adicione INotifyingChangeApplierTarget
à sua lista de herança de classe.
class ContactsProviderXmlMetadataNoChangeUnits : KnowledgeSyncProvider
, INotifyingChangeApplierTarget
Adicione os métodos INotifyingChangeApplierTarget à sua classe.
Propriedade IdFormats
O Sync Framework chama IdFormats para recuperar o esquema de formato de ID do provedor. Este exemplo usa a mesma classe para implementar KnowledgeSyncProvider e INotifyingChangeApplierTarget. Portanto, essa implementação é igual à da propriedade IdFormats de KnowledgeSyncProvider, acima.
GetNextTickCount
O Sync Framework chama GetNextTickCount para incrementar e recuperar a contagem em escala da réplica. Essa implementação chama o método GetNextTickCount do repositório de metadados.
public ulong GetNextTickCount()
{
return _itemStore.ContactReplicaMetadata.GetNextTickCount();
}
A implementação de repositório de metadados de GetNextTickCount incrementa e retorna a contagem em escala da réplica.
public override ulong GetNextTickCount()
{
return ++_tickCount;
}
SaveItemChange
Durante a aplicação de alterações, o Sync Framework chama SaveItemChange para cada alteração a ser aplicada à réplica de destino. Essa implementação atualiza o repositório de itens e o repositório de metadados de cada tipo de alteração recebida. Quando um item é criado ou atualizado, os dados de item são recebidos na propriedade ChangeData do parâmetro context
. A propriedade ChangeData contém o object retornado do método LoadChangeData do provedor de origem. Após a aplicação da alteração, o conhecimento de destino atualizado é armazenado.
public void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context)
{
switch (saveChangeAction)
{
// Update the item store and metadata store when an item is created or updated.
case SaveChangeAction.Create:
case SaveChangeAction.UpdateVersionAndData:
{
try
{
_itemStore.UpdateContactFromSync(change, (string)context.ChangeData);
}
catch (Exception ex)
{
RecoverableErrorData errData = new RecoverableErrorData(ex);
context.RecordRecoverableErrorForItem(errData);
}
break;
}
// Update only the version of this item in the metadata store.
case SaveChangeAction.UpdateVersionOnly:
{
try
{
_itemStore.UpdateContactVersion(change.ItemId, change.ChangeVersion);
}
catch (Exception ex)
{
RecoverableErrorData errData = new RecoverableErrorData(ex);
context.RecordRecoverableErrorForItem(errData);
}
break;
}
// Delete the item from the item store and store a tombstone for it in the metadata store.
case SaveChangeAction.DeleteAndStoreTombstone:
{
try
{
_itemStore.DeleteContactFromSync(change.ItemId, change.ChangeVersion);
}
catch (Exception ex)
{
RecoverableErrorData errData = new RecoverableErrorData(ex);
context.RecordRecoverableErrorForItem(errData);
}
break;
}
// Neither merging of data nor removing tombstones is supported.
case SaveChangeAction.UpdateVersionAndMergeData:
case SaveChangeAction.DeleteAndRemoveTombstone:
{
throw new NotImplementedException();
}
default:
{
throw new ArgumentOutOfRangeException();
}
}
// Save the knowledge in the metadata store as each change is applied. Saving knowledge as each change is applied is
// not required. It is more robust than saving the knowledge only after each change batch, because if synchronization is interrupted
// before the end of a change batch, the knowledge will still reflect all of the changes applied. However, it is less efficient because
// knowledge must be stored more frequently.
SyncKnowledge knowledge;
ForgottenKnowledge forgottenKnowledge;
context.GetUpdatedDestinationKnowledge(out knowledge, out forgottenKnowledge);
_itemStore.ContactReplicaMetadata.SetKnowledge(knowledge);
}
Nos exemplos seguintes, _ContactItemMetaList
contém objetos ItemMetadata.
O método UpdateContactFromSync
do repositório de contatos atualiza o contato especificado. Se o contato não existir, um novo será criado e adicionado ao repositório de contatos. O repositório de metadados também é atualizado para refletir as alterações do repositório de contatos.
public void UpdateContactFromSync(ItemChange itemChange, string changeData)
{
// If the item does not exist, create a new contact and add it to the contact and metadata store.
if (!_ContactList.ContainsKey(itemChange.ItemId))
{
Contact contact = new Contact();
ItemMetadata newItemMeta = _ContactReplicaMetadata.CreateItemMetadata(itemChange.ItemId,
itemChange.CreationVersion);
_ContactList.Add(newItemMeta.GlobalId, contact);
_ContactItemMetaList.Add(newItemMeta.GlobalId, newItemMeta);
}
// Update the specified contact in the contact store. changeData is the contact data returned by the
// IChangeDataRetriever.LoadChangeData method of the source provider.
_ContactList[itemChange.ItemId].FromString(changeData);
// Get the metadata for the specified item.
ItemMetadata itemMeta = _ContactItemMetaList[itemChange.ItemId];
// Update the index fields for the item. This implementation defines an index that uniquely identifies each contact.
// The index consists of the first name, last name, and phone number of the contact.
itemMeta.SetCustomField(FirstNameField, _ContactList[itemChange.ItemId].FirstName);
itemMeta.SetCustomField(LastNameField, _ContactList[itemChange.ItemId].LastName);
itemMeta.SetCustomField(PhoneNumberField, _ContactList[itemChange.ItemId].PhoneNumber);
// Update the version for the change.
itemMeta.ChangeVersion = itemChange.ChangeVersion;
}
O método UpdateContactVersion
do repositório de contatos atualiza os metadados de versão do item especificado.
public void UpdateContactVersion(SyncId itemId, SyncVersion itemVersion)
{
// Update the version metadata for the specified item.
_ContactItemMetaList[itemId].ChangeVersion = itemVersion;
}
O método DeleteContactFromSync
do repositório de contatos remove o item do repositório de contatos e marca o item como excluído no repositório de metadados.
public void DeleteContactFromSync(SyncId itemId, SyncVersion version)
{
if (_ContactList.ContainsKey(itemId))
{
// Remove the item from the contact store.
_ContactList.Remove(itemId);
// Mark the item as deleted in the metadata store.
ItemMetadata itemMeta = _ContactItemMetaList[itemId];
itemMeta.MarkAsDeleted(version);
// Change the first index field so the index fields don't collide with future items.
itemMeta.SetCustomField(FirstNameField, itemId.ToString());
// Move the metadata for the deleted item to a separate list.
// The deleted item metadata must be kept so that it can be committed when
// SaveChanges is called.
_ContactDeletedItemMetaList.Add(itemMeta);
_ContactItemMetaList.Remove(itemId);
}
else
{
// An item marked as deleted has been received as part of synchronization, but it does not exist in
// the item store. Create a tombstone for it in the metadata store.
ItemMetadata itemMeta = _ContactReplicaMetadata.CreateItemMetadata(itemId, version);
itemMeta.MarkAsDeleted(version);
// Clear the index fields so they don't collide with future items.
itemMeta.SetCustomField(FirstNameField, itemId.ToString());
_ContactDeletedItemMetaList.Add(itemMeta);
}
}
StoreKnowledgeForScope
Depois de processar cada lote de alterações, o Sync Framework chama StoreKnowledgeForScope de forma que o provedor de destino possa salvar o conhecimento que contém as novas alterações. Essa implementação salva os objetos de conhecimento no repositório de metadados e substitui o conhecimento anterior existente. As alterações feitas no repositório de contatos e no repositório de metadados durante o processamento do lote de alterações são confirmadas nos arquivos do disco.
public void StoreKnowledgeForScope(SyncKnowledge knowledge, ForgottenKnowledge forgottenKnowledge)
{
_itemStore.ContactReplicaMetadata.SetKnowledge(knowledge);
// Commit changes made to the in-memory item store to the file on disk.
_itemStore.SaveContactChanges();
// Commit changes made to the in-memory metadata store to the file on disk.
_itemStore.SaveMetadataChanges();
}
O método SaveMetadataChanges
do repositório de contatos confirma as alterações feitas no repositório de metadados no arquivo do disco.
public void SaveMetadataChanges()
{
// A transaction is required for saving changes to the metadata store.
_ContactMetadataStore.BeginTransaction(IsolationLevel.ReadCommitted);
// Enumerate the deleted items list.
if (null != _ContactDeletedItemMetaList)
{
foreach (ItemMetadata contactMeta in _ContactDeletedItemMetaList)
{
// Save the deleted item metadata to the metadata store.
_ContactReplicaMetadata.SaveItemMetadata(contactMeta);
}
}
// Save renamed items first to avoid collisions in the metadata store.
foreach (SyncId itemId in _ContactRenameList)
{
_ContactReplicaMetadata.SaveItemMetadata(_ContactItemMetaList[itemId]);
}
// Enumerate the active contacts.
for (int iCon = 0; iCon < _ContactItemMetaList.Count; iCon++)
{
// Save the item metadata to the metadata store.
_ContactReplicaMetadata.SaveItemMetadata(_ContactItemMetaList.Values[iCon]);
}
// Save the replica metadata to the metadata store.
_ContactReplicaMetadata.SaveReplicaMetadata();
// Commit the metadata store transaction.
_ContactMetadataStore.CommitTransaction();
}
Métodos não implementados
Os seguintes métodos não são necessários em cenários de sincronização básica e podem gerar NotImplementedException:
Implementando IChangeDataRetriever
IChangeDataRetriever é retornado para o Sync Framework pelo provedor de origem, em resposta à chamada GetChangeBatch. IChangeDataRetriever é enviado ao provedor de destino na chamada ProcessChangeBatch, em que ele geralmente é passado para o método ApplyChanges de um aplicador de alterações. O aplicador de alterações chama LoadChangeData para obter um object que representa os dados do item. O aplicador de alterações passa essa interface para o método SaveItemChange ou SaveChangeWithChangeUnits do provedor de destino. O provedor de destino usa esse object para recuperar dados de itens novos ou alterados e aplica esses dados à réplica de destino.
Declarando IChangeDataRetriever
Adicione IChangeDataRetriever
à lista de herança de classe.
class ContactsProviderXmlMetadataNoChangeUnits : KnowledgeSyncProvider
, INotifyingChangeApplierTarget
, IChangeDataRetriever
Adicione os métodos IChangeDataRetriever à classe.
Propriedade IdFormats
O Sync Framework chama IdFormats para recuperar o esquema de formato de ID do provedor. Este exemplo usa a mesma classe para implementar KnowledgeSyncProvider e IChangeDataRetriever. Portanto, essa implementação é igual à da propriedade IdFormats de KnowledgeSyncProvider, acima.
Método LoadChangeData
Durante a aplicação de alterações, o Sync Framework chama LoadChangeData para obter um object que o provedor de destino pode usar para recuperar dados de item. Essa implementação retorna os dados de contato serializados como uma cadeia de caracteres.
public object LoadChangeData(LoadChangeContext loadChangeContext)
{
// Return the specified contact serialized as a string.
return _itemStore.ContactList[loadChangeContext.ItemChange.ItemId].ToString();
}
Próximas etapas
Em seguida, você pode criar um aplicativo para hospedar a sessão de sincronização e conectá-lo ao provedor. Para obter informações sobre como fazer isso, consulte Como criar um aplicativo de sincronização não gerenciado.
Você também pode aperfeiçoar o provedor para filtrar os itens ou as unidades de alteração sincronizadas. Para obter mais informações sobre filtragem, consulte Filtrando dados de sincronização.
Você também pode aperfeiçoar o provedor para manipular unidades de alteração. Para obter mais informações sobre unidades de alteração, consulte Sincronizando unidades de alteração.
Você também pode criar um repositório de metadados personalizado. Para obter mais informações sobre como manipular metadados de sincronização, consulte Gerenciando metadados para provedores padrão.
Consulte também
Referência
SyncProvider
KnowledgeSyncProvider
INotifyingChangeApplierTarget
IChangeDataRetriever
NotifyingChangeApplier
Conceitos
Implementando um provedor personalizado padrão
Componentes principais do Sync Framework