이 항목에서는 관리되는 언어를 사용하여 사용자 지정 데이터 저장소의 데이터를 동기화하는 Sync Framework 동기화 공급자를 만드는 방법을 설명합니다.
이 항목에서는 기본적인 C# 및 Microsoft .NET Framework 개념에 익숙하다고 가정합니다.
이 항목의 예제에서는 다음과 같은 Sync Framework 클래스 및 인터페이스를 중점적으로 설명합니다.
동기화 공급자 이해
동기화 공급자는 동기화 도중 복제본을 나타내는 소프트웨어 구성 요소입니다. 이를 통해 복제본의 데이터를 다른 복제본과 동기화할 수 있습니다. 동기화를 수행하려면 우선 응용 프로그램에서 SyncOrchestrator 개체를 만들어 두 SyncProvider 개체에 연결한 다음 동기화를 시작해야 합니다. 공급자 중 하나는 원본 복제본을 나타냅니다. 원본 복제본은 GetChangeBatch 메서드를 통해 변경된 항목에 대한 메타데이터를 제공하고 IChangeDataRetriever 개체를 통해 항목 데이터를 제공합니다. 다른 공급자는 대상 복제본을 나타냅니다. 대상 복제본은 ProcessChangeBatch 메서드를 통해 변경된 항목에 대한 메타데이터를 수신하고, Sync Framework에서 제공하는 NotifyingChangeApplier 개체와 자체 INotifyingChangeApplierTarget 개체를 함께 사용하여 변경 내용을 항목 저장소에 적용합니다.
동기화 공급자의 역할에 대한 자세한 내용은 표준 사용자 지정 공급자 구현를 참조하십시오.
빌드 요구 사항
.NET Framework 2.0 이상
Microsoft.Synchronization에 대한 참조
예제
이 항목의 예제 코드에서는 복제본이 Sync Framework 동기화 커뮤니티에 원본 및 대상으로 참가하는 데 필요한 기본적인 클래스 및 인터페이스 메서드를 구현하는 방법을 보여 줍니다. 이 예제의 복제본은 연락처 정보를 쉼표로 구분된 값의 목록으로 저장하는 텍스트 파일입니다. 동기화할 항목은 이 파일에 포함된 연락처입니다. 또한 이 예제에서는 Metadata Storage Service API를 사용하여 구현된 사용자 지정 메타데이터 저장소를 사용합니다. Metadata Storage Service에 대한 자세한 내용은 Sync Framework Metadata Storage Service를 참조하십시오.
다음 예제에서는 _itemStore가 항목 저장소와 메타데이터 저장소를 모두 포함하는 개체를 나타냅니다.
SyncProvider 및 KnowledgeSyncProvider 구현
공급자의 진입점은 SyncProvider 클래스입니다. 이 클래스는 보다 강력한 다른 공급자 클래스의 기본 클래스 역할을 합니다. 이 예제에서는 KnowledgeSyncProvider 클래스를 사용합니다.
KnowledgeSyncProvider 선언
클래스 상속 목록에 KnowledgeSyncProvider를 추가합니다.
class ContactsProviderXmlMetadataNoChangeUnits : KnowledgeSyncProvider
클래스에 SyncProvider 및 KnowledgeSyncProvider 메서드를 추가합니다.
IdFormats 속성
SyncOrchestrator 개체에서 Synchronize가 호출되면 Sync Framework에서 원본 및 대상 공급자에 대해 IdFormats를 호출합니다. IdFormats 속성은 공급자에서 사용되는 ID 형식 스키마를 반환합니다. 이 스키마는 두 공급자에서 동일해야 합니다. 이 예제에서는 SyncGlobalId가 포함된 항목 ID, 복제본의 절대 경로가 포함된 복제본 ID 및 열거형의 멤버인 변경 단위 ID의 크기를 정의합니다.
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를 사용하여 변경 내용 일괄 처리를 반환합니다. 이 구현에서는 메타데이터 저장소의 항목을 항목 ID별로 정렬된 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에서 검색된 변경 내용 일괄 처리마다 한 번씩 호출됩니다. 이 구현에서는 메타데이터 저장소 개체를 사용하여 항목의 로컬 버전 정보를 원본 공급자에서 가져옵니다. 그런 다음 Sync Framework에서 구현된 NotifyingChangeApplier 개체를 만들고 해당 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 구현
이 인터페이스는 대상 공급자가 일반적으로 ProcessChangeBatch 메서드에서 ApplyChanges 메서드를 호출할 때 Sync Framework에 제공됩니다. INotifyingChangeApplierTarget에는 변경 내용을 적용하는 동안 호출되는 메서드가 들어 있습니다. 이러한 메서드는 대상 공급자에 대해서만 호출됩니다.
INotifyingChangeApplierTarget 선언
클래스 상속 목록에 INotifyingChangeApplierTarget을 추가합니다.
class ContactsProviderXmlMetadataNoChangeUnits : KnowledgeSyncProvider
, INotifyingChangeApplierTarget
클래스에 INotifyingChangeApplierTarget 메서드를 추가합니다.
IdFormats 속성
Sync Framework에서 IdFormats를 호출하여 공급자의 ID 형식 스키마를 검색합니다. 이 예제에서는 같은 클래스를 사용하여 KnowledgeSyncProvider와 INotifyingChangeApplierTarget을 모두 구현합니다. 따라서 이 구현은 위에 있는 KnowledgeSyncProvider의 IdFormats 속성 구현과 같습니다.
GetNextTickCount
Sync Framework에서 GetNextTickCount를 호출하여 복제본의 틱 수를 늘리고 검색합니다. 이 구현에서는 메타데이터 저장소 개체의 GetNextTickCount 메서드를 호출합니다.
public ulong GetNextTickCount()
{
return _itemStore.ContactReplicaMetadata.GetNextTickCount();
}
GetNextTickCount의 메타데이터 저장소 구현은 복제본의 틱 수를 늘리고 반환합니다.
public override ulong GetNextTickCount()
{
return ++_tickCount;
}
SaveItemChange
변경 내용을 적용하는 동안 Sync Framework에서 대상 복제본에 적용할 각 변경 내용에 대해 SaveItemChange를 호출합니다. 이 구현에서는 수신한 각 변경 내용 형식에 대해 항목 저장소와 메타데이터 저장소를 업데이트합니다. 항목이 만들어지거나 업데이트되면 항목 데이터가 context 매개 변수의 ChangeData 속성에서 수신됩니다. ChangeData 속성에는 원본 공급자의 LoadChangeData 메서드에서 반환된 object가 들어 있습니다. 변경 내용이 적용된 후 업데이트된 대상 정보가 저장됩니다.
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 구현
원본 공급자는 GetChangeBatch 호출에 대한 응답으로 IChangeDataRetriever를 Sync Framework에 반환합니다. IChangeDataRetriever는 ProcessChangeBatch 호출 시 대상 공급자에 전송되며 이 호출에서 대개 변경 내용 적용자의 ApplyChanges 메서드에 전달됩니다. 그런 다음 변경 내용 적용자는 LoadChangeData를 호출하여 항목 데이터를 나타내는 object를 가져옵니다. 변경 내용 적용자는 이 인터페이스를 대상 공급자의 SaveItemChange 또는 SaveChangeWithChangeUnits 메서드에 전달합니다. 대상 공급자에서는 이 object를 통해 새 항목이나 변경된 항목의 항목 데이터를 검색하여 대상 복제본에 적용합니다.
IChangeDataRetriever 선언
클래스 상속 목록에 IChangeDataRetriever를 추가합니다.
class ContactsProviderXmlMetadataNoChangeUnits : KnowledgeSyncProvider
, INotifyingChangeApplierTarget
, IChangeDataRetriever
클래스에 IChangeDataRetriever 메서드를 추가합니다.
IdFormats 속성
Sync Framework에서 IdFormats를 호출하여 공급자의 ID 형식 스키마를 검색합니다. 이 예제에서는 같은 클래스를 사용하여 KnowledgeSyncProvider와 IChangeDataRetriever를 모두 구현합니다. 따라서 이 구현은 위에 있는 KnowledgeSyncProvider의 IdFormats 속성 구현과 같습니다.
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