In this topic
- Building the workspace extension
- Extending replica creation with the workspace extension
- Registering the extension
- Creating the replica
- Complete code example
Building the workspace extension
A workspace extension can be created to extend the behavior of a geodatabase. Once created, the extension can be associated with specific geodatabases. It can also be registered on a client machine where it will be applied to any geodatabase accessed on that machine.
For more information on how to build and associate a workspace extension with a geodatabase, see Creating workspace extensions.
Extending replica creation with the workspace extension
With a workspace extension, replica creation can be extended by implementing the IWorkspaceReplicaEvents interface. This interface includes a BeforeCreateChildReplica method and an AfterCreateChildReplica method. During replica creation, these methods are called when the extension is associated with the source geodatabase. The BeforeCreateChildReplica method is called before the internal replica creation behavior has been executed. The AfterCreateChildReplica is called once the internal replica creation behavior has been completed.
Add code to the BeforeCreateChildReplica method to ensure that certain options are applied during replica creation. This method allows the replica description to be changed before it is used by the internal replica creation process. This way, the default replica creation behavior can be altered. For example, new feature classes and tables could be added to the replica, the filters could be changed, or feature classes and tables that are already set to be replicated could be removed.
The AfterCreateChildReplica method can be used to add code to augment the replica creation process with additional behavior. The code example shows how to augment replica creation by copying a nonversioned table from the source geodatabase to the target geodatabase. This can be done by adding code to the AfterCreateChildReplica method. If there is a failure during the internal replica creation process, this method will not be called and code will not have to be added to clean up the target geodatabase.
The following code example shows an implementation of the AfterCreateChildReplica method that copies a table (LookupTable) from the source geodatabase to the target geodatabase. In this code example, LookupTable is not part of the replica since it is not versioned in the source geodatabase.
[C#]
public void AfterCreateChildReplica(String name, esriReplicaType replicaType,
IReplicaDescription replicaDesc, IWorkspace childWorkspace)
{
// Get the source geodatabase. Note: This is stored in a global variable in the extension.
IWorkspace parentWorkspace = workspaceHelper.Workspace;
IDataset parentDataset = (IDataset)parentWorkspace;
IWorkspaceName parentWorkspaceName = (IWorkspaceName)parentDataset.FullName;
// Add the table (LookupTable) to a Names enumerator.
IEnumName enumName = new NamesEnumeratorClass();
IEnumNameEdit enumNameEdit = (IEnumNameEdit)enumName;
ITableName tableName = new TableNameClass();
IDatasetName datasetName = (IDatasetName)tableName;
datasetName.WorkspaceName = parentWorkspaceName;
datasetName.Name = "LookupTable";
IName lookupName = (IName)datasetName;
enumNameEdit.Add(lookupName);
// Initialize the replica description using the passed in target geodatabase.
IReplicaDescription replicaDescription = new ReplicaDescriptionClass();
IDataset replicaDataset = (IDataset)childWorkspace;
IName replicaName = replicaDataset.FullName;
IWorkspaceName replicaWorkspaceName = (IWorkspaceName)replicaName;
replicaDescription.Init(enumName, replicaWorkspaceName, false,
esriDataExtractionType.esriDataExtraction);
// Set the filter for the table to all rows.
int tableIndex = replicaDescription.FindTable(lookupName);
IReplicaFilterDescriptionEdit replicaFilterDescEdit =
(IReplicaFilterDescriptionEdit)replicaDescription;
replicaFilterDescEdit.set_RowsType(tableIndex, esriRowsType.esriRowsTypeAll);
// Run a data extraction to copy the table to the target geodatabase.
IDataExtraction dataExtraction = new DataExtractionClass();
try
{
dataExtraction.Extract(replicaDescription, false);
}
catch (COMException comExc)
{
// Handle appropriately for your application.
throw comExc;
}
}
[VB.NET]
Public Sub AfterCreateChildReplica(ByVal Name As String, ByVal replicaType As esriReplicaType, _
ByVal replicaDesc As IReplicaDescription, ByVal childWorkspace As IWorkspace) _
Implements IWorkspaceReplicaEvents.BeforeCreateChildReplica
' Get the source geodatabase. Note: This is stored in a global variable in the extension.
Dim parentWorkspace As IWorkspace = workspaceHelper.Workspace
Dim parentDataset As IDataset = CType(parentWorkspace, IDataset)
Dim parentWorkspaceName As IWorkspaceName = CType(parentDataset.FullName, IWorkspaceName)
' Add the table (LookupTable) to a Names enumerator.
Dim enumName As IEnumName = New NamesEnumeratorClass()
Dim enumNameEdit As IEnumNameEdit = CType(enumName, IEnumNameEdit)
Dim tableName As ITableName = New TableNameClass()
Dim datasetName As IDatasetName = CType(tableName, IDatasetName)
datasetName.WorkspaceName = parentWorkspaceName
datasetName.Name = "LookupTable"
Dim lookupName As IName = CType(datasetName, IName)
enumNameEdit.Add(lookupName)
' Initialize the replica description using the passed in target geodatabase.
Dim replicaDescription As IReplicaDescription = New ReplicaDescriptionClass()
Dim replicaDataset As IDataset = CType(childWorkspace, IDataset)
Dim replicaName As IName = replicaDataset.FullName
Dim replicaWorkspaceName As IWorkspaceName = CType(replicaName, IWorkspaceName)
replicaDescription.Init(enumName, replicaWorkspaceName, False, esriDataExtractionType.esriDataExtraction)
' Set the filter for the table to all rows.
Dim tableIndex As Integer = replicaDescription.FindTable(lookupName)
Dim replicaFilterDescEdit As IReplicaFilterDescriptionEdit = CType(replicaDescription, IReplicaFilterDescriptionEdit)
replicaFilterDescEdit.RowsType(tableIndex) = esriRowsType.esriRowsTypeAll
' Run a data extraction to copy the table to the target geodatabase.
Dim dataExtraction As IDataExtraction = New DataExtractionClass()
Try
dataExtraction.Extract(replicaDescription, False)
Catch comExc As COMException
Throw comExc
End Try
End Sub
Registering the extension
As previously discussed, a workspace extension can be registered with specific geodatabases or on the client machine. For example, since a specific table is copied from a source geodatabase during replica creation, the extension should be registered with the source geodatabase.
Creating the replica
Once the extension is associated with the source geodatabase, replicas created from that geodatabase execute the code to copy the LookUpTable. This ensures the presence of this table in the target geodatabase.
Any replica creation method can be used. This includes replicas created using the create replica wizard in ArcMap, the create replica and create replica from server geoprocessing tools, or replicas created with the application programming interface (API). For examples of how to create replicas with the API, see How to create a replica in a connected environment and How to create a replica in a disconnected environment.
Although the replica creation process can be extended in a disconnected environment, this particular example will not work. It requires the source and target geodatabases to be available at creation time. However, this example can be used as a starting point for building other applications.
Complete code example
The following is a complete code example of a workspace extension that implements the previously described behavior:
At a minimum, change the globally unique identifier (GUID) attribute parameter to a new value that will be unique. In addition, change the ProgID attribute parameter.
[Guid("97CD2883-37CB-4f76-BD0F-945279C783DC")][ProgId(
"SdkExamples.ReplicaWorkspaceExtensionCS")][ClassInterface
(ClassInterfaceType.None)]
public class ReplicationWorkspaceExtension: IWorkspaceExtensionControl,
IWorkspaceExtension2, IWorkspaceReplicaEvents
{
private IWorkspaceHelper workspaceHelper = null;
#region IWorkspaceExtensionControl members
public void Init(IWorkspaceHelper workspaceHelper)
{
this.workspaceHelper = workspaceHelper;
}
public void Shutdown(){}
#endregion
#region IWorkspaceExtension2 members
public string Name
{
get
{
return "ReplicationWorkspaceExtension";
}
}
public UID GUID
{
get
{
UIDClass uid = new UIDClass();
uid.Value = "{97CD2883-37CB-4f76-BD0F-945279C783DC}";
return uid;
}
}
public IEnumBSTR get_PrivateDatasetNames(esriDatasetType dsType)
{
return null;
}
public IEnumBSTR DataDictionaryTableNames
{
get
{
return null;
}
}
public bool OwnsDatasetType(esriDatasetType datasetType)
{
return false;
}
public IWorkspace Workspace
{
get
{
return workspaceHelper.Workspace;
}
}
#endregion
#region IWorkspaceReplicaEvents members
public void AfterCreateChildReplica(String name, esriReplicaType replicaType,
IReplicaDescription replicaDesc, IWorkspace childWorkspace)
{
// Get the source geodatabase. Note: This is stored in a global variable in the extension.
IWorkspace parentWorkspace = workspaceHelper.Workspace;
IDataset parentDataset = (IDataset)parentWorkspace;
IWorkspaceName parentWorkspaceName = (IWorkspaceName)parentDataset.FullName;
// Add the table (LookupTable) to a Names enumerator.
IEnumName enumName = new NamesEnumeratorClass();
IEnumNameEdit enumNameEdit = (IEnumNameEdit)enumName;
ITableName tableName = new TableNameClass();
IDatasetName datasetName = (IDatasetName)tableName;
datasetName.WorkspaceName = parentWorkspaceName;
datasetName.Name = "LookupTable";
IName lookupName = (IName)datasetName;
enumNameEdit.Add(lookupName);
// Initialize the replica description using the passed in target geodatabase.
IReplicaDescription replicaDescription = new ReplicaDescriptionClass();
IDataset replicaDataset = (IDataset)childWorkspace;
IName replicaName = replicaDataset.FullName;
IWorkspaceName replicaWorkspaceName = (IWorkspaceName)replicaName;
replicaDescription.Init(enumName, replicaWorkspaceName, false,
esriDataExtractionType.esriDataExtraction);
// Set the filter for the table to all rows.
int tableIndex = replicaDescription.FindTable(lookupName);
IReplicaFilterDescriptionEdit replicaFilterDescEdit =
(IReplicaFilterDescriptionEdit)replicaDescription;
replicaFilterDescEdit.set_RowsType(tableIndex, esriRowsType.esriRowsTypeAll);
// Run a data extraction to copy the table to the target geodatabase.
IDataExtraction dataExtraction = new DataExtractionClass();
try
{
dataExtraction.Extract(replicaDescription, false);
}
catch (COMException comExc)
{
// Handle appropriately for your application.
throw comExc;
}
}
public void BeforeCreateChildReplica(String name, esriReplicaType replicaType,
IReplicaDescription replicaDesc, IWorkspace childWorkspace){}
#endregion
}
[VB.NET]
<Guid("71300fc6-cb76-496d-b89f-cf1db2550788")> _
<ProgId("SdkExamples.ReplicaWorkspaceExtensionVB")> _
<ClassInterface(ClassInterfaceType.None)> _
Public Class ReplicationWorkspaceExtension
Implements IWorkspaceExtensionControl, IWorkspaceExtension2, IWorkspaceReplicaEvents
Private workspaceHelper As IWorkspaceHelper = Nothing
#Region "IWorkspaceExtensionControl members"
Public Sub Init(ByVal wsHelper As IWorkspaceHelper) Implements IWorkspaceExtensionControl.Init
workspaceHelper = wsHelper
End Sub
Public Sub Shutdown() Implements IWorkspaceExtensionControl.Shutdown
End Sub
#End Region
#Region "IWorkspaceExtension2 members"
Public ReadOnly Property DataDictionaryTableNames() As IEnumBSTR _
Implements IWorkspaceExtension.DataDictionaryTableNames, IWorkspaceExtension2.DataDictionaryTableNames
Get
Return Nothing
End Get
End Property
Public ReadOnly Property GUID() As UID _
Implements IWorkspaceExtension.GUID, IWorkspaceExtension2.GUID
Get
Dim uid As UIDClass = New UIDClass()
uid.Value = "{71300fc6-cb76-496d-b89f-cf1db2550788}"
Return uid
End Get
End Property
Public ReadOnly Property Name() As String _
Implements IWorkspaceExtension.Name, IWorkspaceExtension2.Name
Get
Return "ReplicationWorkspaceExtension"
End Get
End Property
Public ReadOnly Property PrivateDatasetNames(ByVal dsType As esriDatasetType) As IEnumBSTR _
Implements IWorkspaceExtension.PrivateDatasetNames, IWorkspaceExtension2.PrivateDatasetNames
Get
Return Nothing
End Get
End Property
Public Function OwnsDatasetType(ByVal datasetType As esriDatasetType) As Boolean _
Implements IWorkspaceExtension2.OwnsDatasetType
Return False
End Function
Public ReadOnly Property Workspace() As IWorkspace _
Implements IWorkspaceExtension2.Workspace
Get
Return workspaceHelper.Workspace
End Get
End Property
#End Region
#Region "IWorkspaceReplicaEvents members"
Public Sub AfterCreateChildReplica(ByVal Name As String, ByVal replicaType As esriReplicaType, _
ByVal replicaDesc As IReplicaDescription, ByVal childWorkspace As IWorkspace) _
Implements IWorkspaceReplicaEvents.BeforeCreateChildReplica
' Get the source geodatabase. Note: This is stored in a global variable in the extension.
Dim parentWorkspace As IWorkspace = workspaceHelper.Workspace
Dim parentDataset As IDataset = CType(parentWorkspace, IDataset)
Dim parentWorkspaceName As IWorkspaceName = CType(parentDataset.FullName, IWorkspaceName)
' Add the table (LookupTable) to a Names enumerator.
Dim enumName As IEnumName = New NamesEnumeratorClass()
Dim enumNameEdit As IEnumNameEdit = CType(enumName, IEnumNameEdit)
Dim tableName As ITableName = New TableNameClass()
Dim datasetName As IDatasetName = CType(tableName, IDatasetName)
datasetName.WorkspaceName = parentWorkspaceName
datasetName.Name = "LookupTable"
Dim lookupName As IName = CType(datasetName, IName)
enumNameEdit.Add(lookupName)
' Initialize the replica description using the passed in target geodatabase.
Dim replicaDescription As IReplicaDescription = New ReplicaDescriptionClass()
Dim replicaDataset As IDataset = CType(childWorkspace, IDataset)
Dim replicaName As IName = replicaDataset.FullName
Dim replicaWorkspaceName As IWorkspaceName = CType(replicaName, IWorkspaceName)
replicaDescription.Init(enumName, replicaWorkspaceName, False, esriDataExtractionType.esriDataExtraction)
' Set the filter for the table to all rows.
Dim tableIndex As Integer = replicaDescription.FindTable(lookupName)
Dim replicaFilterDescEdit As IReplicaFilterDescriptionEdit = CType(replicaDescription, IReplicaFilterDescriptionEdit)
replicaFilterDescEdit.RowsType(tableIndex) = esriRowsType.esriRowsTypeAll
' Run a data extraction to copy the table to the target geodatabase.
Dim dataExtraction As IDataExtraction = New DataExtractionClass()
Try
dataExtraction.Extract(replicaDescription, False)
Catch comExc As COMException
' Handle appropriately for your application.
Throw comExc
End Try
End Sub
Public Sub BeforeCreateChildReplica(ByVal Name As String, ByVal rType As esriReplicaType, _
ByVal rDescription As IReplicaDescription, ByVal childWorkspace As IWorkspace) _
Implements IWorkspaceReplicaEvents.AfterCreateChildReplica
End Sub
#End Region
End Class
See Also:
How to create a replica in a connected environmentHow to create a replica in a disconnected environment
Creating workspace extensions
To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
ESRI.ArcGIS.Geodatabase ESRI.ArcGIS.GeoDatabaseDistributed ESRI.ArcGIS.System (ESRI.ArcGIS.esriSystem)System.Runtime.InteropServices
Development licensing | Deployment licensing |
---|---|
ArcEditor | ArcEditor |
ArcInfo | ArcInfo |
Engine Developer Kit | Engine Runtime: Geodatabase Update |