Поделиться через


Как создать управляемую службу синхронизации

В этом разделе описывается использование управляемого языка для создания службы синхронизации платформы Sync Framework, синхронизирующей данные из пользовательского хранилища данных.

Материал этого раздела предполагает, что читатель владеет основными понятиями языка C# и платформы Microsoft .NET Framework.

В примерах, приведенных в этом разделе, обсуждаются следующие классы и интерфейсы платформыSync Framework.

Основные сведения о службах синхронизации

Служба синхронизации — это программный компонент, представляющий реплику во время синхронизации. Это позволяет реплике синхронизировать свои данные с другими репликами. Для выполнения синхронизации приложение вначале создает объект SyncOrchestrator, подключает его к двум объектам SyncProvider и затем начинает сеанс синхронизации. Один из поставщиков представляет реплику источника. Реплика источника поставляет метаданные измененных элементов с помощью своего метода GetChangeBatch и данные элементов с помощью объекта IChangeDataRetriever. Другой поставщик представляет реплику назначения. Реплика назначения получает метаданные измененных элементов через метод ProcessChangeBatch и применяет изменения к своему хранилищу элементов, используя предоставляемый Sync Framework объект NotifyingChangeApplier и собственный объект INotifyingChangeApplierTarget.

Дополнительные сведения о роли службы синхронизации см. в разделе Реализация стандартного пользовательского поставщика.

Требования построения

Пример

В примере кода в этом разделе показана реализация основных методов интерфейса и класса, которые требуются реплике для участия в сообществе синхронизации Sync Framework не только в качестве источника, но и назначения. Реплика в этом примере является текстовым файлом, в котором хранится контактная информация в виде списка значений с разделителями-запятыми. Синхронизируемыми элементами являются контакты, содержащиеся в этом файле. В этом примере также используется пользовательское хранилище метаданных, которое реализуется API-интерфейсом службы хранилища метаданных. Дополнительные сведения о службе хранилища метаданных см. в разделе Служба хранилища метаданных платформы Sync Framework.

В следующих примерах _itemStore представляет объект, содержащий хранилище элементов и хранилище метаданных.

Реализация SyncProvider и KnowledgeSyncProvider

Точкой входа в поставщик является класс SyncProvider. Этот класс предназначен в качестве базового класса для других, более мощных классов поставщика. В этом примере используется класс KnowledgeSyncProvider.

Объявление KnowledgeSyncProvider

Добавьте KnowledgeSyncProvider в список наследования класса.

class ContactsProviderXmlMetadataNoChangeUnits : KnowledgeSyncProvider

Добавьте методы SyncProvider и KnowledgeSyncProvider в класс.

Свойство IdFormats

Sync Framework вызывает метод IdFormats не только в поставщике источника, но и в поставщике назначения, если вызывается метод Synchronize для объекта SyncOrchestrator. Свойство IdFormats возвращает схему форматов идентификаторов, используемую поставщиком. Схема должна быть одинаковой для обоих поставщиков. В этом примере определяются размеры идентификаторов элементов, которые содержат SyncGlobalId, идентификаторы реплики, которые содержат абсолютный путь к реплике, и идентификаторы базовых единиц, которые являются членами перечисления.

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

Метод BeginSession

Sync Framework вызывает метод BeginSession не только в поставщике источника, но и в поставщике назначения перед вызовом других методов. Этот метод сообщает поставщику, что он присоединяется к сеансу синхронизации и передает поставщику объект, содержащий сведения о состоянии сеанса. В этой реализации сохраняется объект состояния сеанса или вызывается исключение SyncInvalidOperationException, если поставщик уже присоединил сеанс синхронизации.

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

Метод GetSyncBatchParameters

Sync Framework вызывает метод GetSyncBatchParameters в поставщике назначения. Этот метод получает число изменений, которые поставщик источника должен включить в пакет изменений, а также текущий набор знаний поставщика назначения. Данная реализация получает набор знаний из хранилища метаданных и присваивает размеру пакета значение 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();
}

Объект хранилища метаданных возвращает текущий набор знаний реплики с помощью метода GetKnowledge. В этой реализации создается новый объект SyncKnowledge, если реплика еще не содержит набор знаний и значение счетчика тактов набора знаний устанавливается равным текущему счетчику тактов реплики.

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

Метод GetChangeBatch

Сеанс синхронизации по-настоящему начинается, когда Sync Framework вызывает метод GetChangeBatch в поставщике источника. Этот метод получает пакет изменений, который нужно отправить поставщику назначения, и возвращает также интерфейс получения данных. Sync Framework использует интерфейс объекта получения данных для получения object, используемого поставщиком назначения, чтобы извлечь данные элемента для изменений, применяемых в реплике назначения. Sync Framework вызывает метод GetChangeBatch до тех пор, пока не будет отправлен последний пакет. Чтобы указать, что пакет был последним, поставщик источника вызывает метод SetLastBatch для объекта пакета изменений. Эта реализация делегирует задачу перечисления изменений объекту хранилища метаданных. Объект поставщика реализует IChangeDataRetriever, поэтому он возвращается в параметре 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);
}

Объект хранилища метаданных возвращает пакет изменений с помощью метода GetChangeBatch. В этой реализации элементы метаданных хранятся в хранилище в виде списка объектов ItemMetadata, упорядоченных по идентификатору элемента. Элементы перечисляются и изменение добавляется в упорядоченную группу в объекте пакета изменений, если изменение не содержится в наборе знаний назначения. После перечисления всех элементов в хранилище метаданных для пакета изменений вызывается метод SetLastBatch.

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

Метод ProcessChangeBatch

После того как Sync Framework получил пакет изменений от поставщика источника с помощью своего метода GetChangeBatch, Sync Framework вызывает метод ProcessChangeBatch в поставщике назначения. Этот метод применяет изменения в реплике назначения. Он вызывается один раз для каждого пакета изменений, который извлекается методом GetChangeBatch из поставщика источника. Эта реализация использует объект хранилища метаданных для получения локальной версии сведений об элементах от поставщика источника. Затем в ней создается объект NotifyingChangeApplier, реализованный Sync Framework, и вызывается метод 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);
}

Объект хранилища метаданных возвращает локальную версию сведений об элементах из поставщика источника с помощью метода GetLocalVersions. В этой реализации перечисляются изменения, отправленные в пакете изменений поставщиком источника. Если элемент находится в метаданных назначения, сведения о его версии добавляются к списку изменений, содержащих сведения о версиях. Если элемент не существует в метаданных назначения, он помечается как неизвестный в списке локальных версий.

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

Метод EndSession

После того как поставщик источника отправил последний пакет, а поставщик назначения применил изменения к хранилищу данных, Sync Framework вызывает метод EndSession как в поставщике источника, так и в поставщике назначения. Этот метод сообщает, что завершает сеанс синхронизации и должен освободить ресурсы. Эта реализация освобождает объект состояния сеанса, который хранится в вызове BeginSession, или вызывает исключение SyncInvalidOperationException, если поставщик ранее не присоединил сеанс синхронизации.

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

Нереализованные методы

Следующие методы не требуются, поскольку этот образец не удаляет элементы, помеченные как удаленные в хранилище метаданных. Эти методы могут вызывать исключение NotImplementedException:

Реализация интерфейса INotifyingChangeApplierTarget

Этот интерфейс предоставляется Sync Framework, когда поставщик назначения вызывает метод ApplyChanges, обычно в методе ProcessChangeBatch. INotifyingChangeApplierTarget содержит методы, вызываемые во время применения изменений. Эти методы вызываются только в поставщике назначения.

Объявление INotifyingChangeApplierTarget

Добавьте INotifyingChangeApplierTarget к списку наследования классов.

class ContactsProviderXmlMetadataNoChangeUnits : KnowledgeSyncProvider
    , INotifyingChangeApplierTarget

Добавьте методы INotifyingChangeApplierTarget в класс.

Свойство IdFormats

Sync Framework вызывает метод IdFormats для получения схемы форматов идентификаторов поставщика. В этом примере для реализации методов KnowledgeSyncProvider и INotifyingChangeApplierTarget используется один и тот же класс. Поэтому используется такая же реализация, как и указанная выше для свойства IdFormats поставщика KnowledgeSyncProvider.

GetNextTickCount

Sync Framework вызывает метод GetNextTickCount для приращения счетчика тактов реплики и получения его значения. Эта реализация вызывает метод GetNextTickCount объекта хранилища метаданных.

public ulong GetNextTickCount()
{
    return _itemStore.ContactReplicaMetadata.GetNextTickCount();
}

В реализации метода GetNextTickCount хранилища метаданных увеличивается и возвращается значение счетчика тактов реплики.

public override ulong GetNextTickCount()
{
    return ++_tickCount;
}

SaveItemChange

Во время применения изменений Sync Framework вызывает SaveItemChange для каждого изменения, применяемого в реплике назначения. Эта реализация обновляет хранилище элементов и метаданных для каждого полученного типа изменений. При создании или обновлении элемента данные элемента получаются в свойстве ChangeData параметра context. Свойство ChangeData содержит object, возвращенный из метода LoadChangeData поставщика источника. После применения изменения обновленный набор знаний назначения сохраняется.

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

В следующих примерах _ContactItemMetaList содержит объекты ItemMetadata.

Метод UpdateContactFromSync хранилища контактов обновляет указанный контакт. Если контакт не существует, то создается новый контакт, который добавляется к хранилищу контактов. Хранилище метаданных также обновляется, отражая изменения в хранилище контактов.

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

Метод UpdateContactVersion хранилища контактов обновляет метаданные версии для указанного элемента.

public void UpdateContactVersion(SyncId itemId, SyncVersion itemVersion)
{
    // Update the version metadata for the specified item.
    _ContactItemMetaList[itemId].ChangeVersion = itemVersion;
}

Метод DeleteContactFromSync хранилища контактов удаляет элемент из хранилища контактов и отмечает элемент как удаленный в хранилище метаданных.

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

После обработки каждого пакета изменений Sync Framework вызывает метод StoreKnowledgeForScope, чтобы поставщик назначения сохранил набор знаний, содержащий новые изменения. Эта реализация сохраняет объекты набора знаний в хранилище метаданных, перезаписывая существующий набор знаний. Изменения, сделанные в хранилище контактов и хранилище метаданных во время обработки пакета изменений, фиксируются в файлах на диске.

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

Метод SaveMetadataChanges хранилища контактов фиксирует изменения, сделанные в хранилище метаданных (в файлах на диске).

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

Нереализованные методы

Следующие методы не требуются базовым сценариям синхронизации и могут вызывать исключение NotImplementedException.

Реализация интерфейса IChangeDataRetriever

Метод IChangeDataRetriever возвращается платформами Sync Framework поставщиком источника в ответ на вызов метода GetChangeBatch. Метод IChangeDataRetriever отправляется поставщику назначения в вызове ProcessChangeBatch, где он обычно передается методу применения изменений ApplyChanges. После этого объект применения изменений вызывает метод LoadChangeData, чтобы получить object, представляющий данные элемента. Объект применения изменений передает этот интерфейс методу SaveItemChange или SaveChangeWithChangeUnits поставщика назначения. Поставщик назначения использует этот object для получения данных элементов для новых или изменившихся элементов и применяет эти данные элементов в реплике назначения.

Объявление IChangeDataRetriever

Добавьте IChangeDataRetriever в список наследования класса.

class ContactsProviderXmlMetadataNoChangeUnits : KnowledgeSyncProvider
    , INotifyingChangeApplierTarget
    , IChangeDataRetriever

Добавьте методы IChangeDataRetriever в класс.

Свойство IdFormats

Sync Framework вызывает метод IdFormats для получения схемы форматов идентификаторов поставщика. В этом примере для реализации методов KnowledgeSyncProvider и IChangeDataRetriever используется один и тот же класс. Поэтому используется такая же реализация, как и указанная выше для свойства IdFormats поставщика KnowledgeSyncProvider.

Метод LoadChangeData

Во время применения изменений Sync Framework вызывает метод LoadChangeData для получения object, который поставщик назначения может использовать для получения данных элементов. Эта реализация возвращает данные контактов, сериализованные в виде строки.

public object LoadChangeData(LoadChangeContext loadChangeContext)
{
    // Return the specified contact serialized as a string.
    return _itemStore.ContactList[loadChangeContext.ItemChange.ItemId].ToString();
}

Следующие шаги

Затем можно создать приложение, включающее сеанс синхронизации, и присоединить его к поставщику. Сведения о том, как это сделать, см. в разделе Как создать неуправляемое приложение синхронизации.

Также можно расширить возможности поставщика, добавив фильтр для элементов или базовых единиц, которые должны синхронизироваться. Дополнительные сведения о фильтрации см. в разделе Фильтрация данных синхронизации.

Также можно улучшить поставщик, включив в него обработку базовых единиц. Дополнительные сведения о базовых единицах см. в разделе Синхронизация базовых единиц.

Можно также создать пользовательское хранилище метаданных. Дополнительные сведения об обработке метаданных синхронизации см. в разделе Управление метаданными для стандартных поставщиков.

См. также

Справочник

SyncProvider
KnowledgeSyncProvider
INotifyingChangeApplierTarget
IChangeDataRetriever
NotifyingChangeApplier

Основные положения

Реализация стандартного пользовательского поставщика
Базовые компоненты Sync Framework