How to: Track Filters and Enumerate Filtered Changes
This topic describes how to use a managed language to track filters that are used in a Sync Framework synchronization community, and how to enumerate a filtered change batch.
This topic assumes a basic familiarity with C# and Microsoft .NET Framework concepts.
The examples in this topic focus on the following Sync Framework classes and members:
Understanding Filter Tracking
It is recommended that all replicas in a synchronization community track the filters that are used in the community. When a filtered replica receives a filtered change enumeration from a filter-tracking replica, the knowledge of the filtered replica is kept small. When a filtered replica receives a filtered change enumeration from a replica that does not track the filter, the size of the knowledge grows in proportion to the number of changes sent.
A filter-tracking provider implements the IFilterTrackingProvider interface. Sync Framework uses this interface to mediate the negotiation of which filters are tracked by both the source replica and the destination replica.
The source provider sends filter metadata for each mutually tracked filter during synchronization. A filter-tracking provider typically also implements the ISupportFilteredSync interface and is able to enumerate changes that are filtered by any of the tracked filters.
The destination provider implements the IFilterTrackingNotifyingChangeApplierTarget interface, which the change applier uses to obtain and update the filter key map and filter forgotten knowledge of tracked filters. The destination provider also updates the filter change metadata of items and change units that are sent to the SaveItemChange(SaveChangeAction, ItemChange, SaveChangeContext) or SaveChangeWithChangeUnits(ItemChange, SaveChangeWithChangeUnitsContext) method.
.NET Framework 2.0 or later.
Reference to Microsoft.Synchronization.
Reference to Microsoft.Synchronization.MetadataStorage.
The example code in this topic shows how to implement a filter-tracking provider that sends filter change metadata and can enumerate a filtered change batch when acting as the source provider, and that applies filter change metadata when acting as the destination provider. The replica in this example is a text file that stores contact information as a list of comma-separated values. The items to synchronize are the contacts that are contained in this file. A filter is a string that causes a contact to be included only if the filter string is found in the address field of the contact.
Negotiating Tracked Filters
To negotiate the tracked filters, Sync Framework calls SpecifyTrackedFilters(RequestTrackedFilterCallback) on the destination provider. This example enumerates the list of filters tracked by the destination replica, sends each filter to the source provider, and adds the filter to the list of mutually tracked filters only when the source provider also tracks the filter.
For each filter that is enumerated by the destination provider, Sync Framework calls the TryAddTrackedFilter(ISyncFilter) method of the source provider. This example checks whether the specified filter is tracked by the source replica and, if it is, adds it to the list of mutually tracked filters.
Negotiating the Filter Used for Synchronization
When the destination replica is a filtered replica, it typically requests the filter that the source provider uses to enumerate changes. The source provider receives this request through the TryAddFilter(Object) method. This example checks whether the requested filter is a mutually tracked filter and, if it is, saves it to use when enumerating changes.
Sending Filter Metadata and Filtered Changes
The source provider sends filter metadata when it sends a batch of changes. This example can send either a filtered change batch or an unfiltered change batch, depending on whether a filter is used for synchronization. Each change that is included in the change batch has filter change metadata attached to it when the item has changed in relation to a tracked filter. Filter forgotten knowledge for each tracked filter is also sent. When a filter is used for synchronization, an item is sent when it is in the filter, and an item that has moved out of the filter is marked as a ghost.
Filter change metadata is examined for each mutually tracked filter. Filter change metadata is added to a change when the move version of the change is not contained in the destination knowledge.
Applying Filter Metadata
Changes are applied by using a change applier, which calls the SaveItemChange(SaveChangeAction, ItemChange, SaveChangeContext) method of the destination provider. When an item is created or updated, this example creates or updates the data in the contact store, updates the synchronization metadata, and updates the filter tracking metadata. Filter tracking metadata is updated for all filters that are tracked by the destination provider, not just for mutually tracked filters. When filter metadata is sent by the source provider, it is used, otherwise the change is compared to each tracked filter and the appropriate filter change metadata is set.
The change applier also calls the methods of the IFilterTrackingNotifyingChangeApplierTarget interface of the destination provider to obtain and save filter tracking metadata. This example returns the requested objects and saves the specified metadata.
Storing Filter Metadata
The filters that are tracked by a replica must be stored in the replica, along with the filter forgotten knowledge of each tracked filter. This example uses the metadata storage service to store metadata. The metadata storage service does not support custom filters, so tracked filters are serialized to a byte stream and stored in the custom replica metadata field of the metadata store.
Each item tracks whether it is in a filter, and the version of the change that caused the item to move into or out of the filter. This example stores the filter tracking metadata for an item as custom item fields in the metadata store.
Next, you might want to add filter negotiation to your provider so that it can communicate with the destination provider to establish which filter to use for change enumeration. For more information on how to negotiate filters, see How to: Negotiate a Filter.
You may also want to enable your provider to represent a filtered replica when it is the destination provider. For more information on how to implemented a filtered provider, see How to: Filter a Replica.