Data Designer Extensibility Architecture
Data Designer Extensibility (DDEX) provides a mechanism for extending data designers in Visual Studio to communicate with external data sources and expose their object hierarchies and allow hierarchy views in Server Explorer. DDEX allows access to external data source objects at design time, not only providing data object visibility in Visual Studio, but also enabling drag-and-drop functionality, object property grid visibility, and integration into features of the Visual Studio designers. In short, DDEX allows providers of third-party data sources to enjoy full citizenship in the Visual Studio design-time experience.
DDEX providers are different from .NET data providers. For more information, see DDEX Providers.
Data Designer Extensibility, then, is about using the DDEX SDK and the feature's architecture and managed APIs to integrate external data source objects into the Visual Studio environment.
This SDK should be used in conjunction with Extending Visual Studio Overview.
The illustration below provides a high-level, schematic view of the DDEX architecture. In it, you see that the DDEX client is hosted in Visual Studio, and that it uses the access and core services (part of the DDEX managed class library) to communicate and interact with a DDEX provider. The DDEX provider itself is simply an implementation of the support entities, which are managed classes. DDEX then communicates with the data layer using a dedicated .NET data provider. Note, however, that the data provider can be omitted in cases where the DDEX provider is equipped with the capability needed to interact with the data source.
Of the DDEX layer, two of its pieces are central: DDEX support entities and DDEX services.
DDEX support entities are interfaces that a DDEX provider implements to enable data extensibility. In fact, it is the implementation of these support entities that constitutes a DDEX provider.
DDEX services, on the other hand, are broken up into core services and access services. Core services are the base services through which the support entities are exposed. They are interfaces implemented internally as managed classes that Visual Studio calls to create top-level DDEX provider support entities, and to work with data providers and data sources. Access services, which are also interfaces internally implemented as managed classes, provide Visual Studio with the ability to create and work with data connections and to have access to the in-memory data structure representations of the data object support XML and data view support XML. Also, access services consume support entities.
The illustration below depicts the relationship between support entities and services in more detail.
The managed APIs that constitute a DDEX provider fall broadly into three categories:
Data object support
Data view support
Connection support provides a way to specify connection information, including data source and connection string. This can be done either programmatically, if the connection information is known, or by using connection UI to prompt the user for the required connection information. Optionally, a DDEX provider can expose a connection control that is hosted in the Visual Studio connection dialog box.
Using a data object support XML file, a DDEX provider defines data objects exposed by the data provider for a given data source. It also defines the object hierarchy, or object model, for these objects.
The Visual Studio metadata engine maintains a library of strongly typed classes that allow it to recognize generic data-source object like tables, views, and stored procedures, as well as generic object properties, all of which it reduces to mapped types. The data object definitions provided in your XML file allow you to map object types supported by your data provider to one of these generic types that are recognized by the metadata engine.
In addition to defining object types and mapping them to generic types, your data object support schema must also specify the following:
How to enumerate objects of specified type, which is done by specifying a handler that is called when enumerating object is required.
How to retrieve metadata object metadata, such as object identifier or object properties.
How to construct a clipboard object in cases where a copy operation is performed on an object of the specified type. Visual Studio data designers use the Data Source Reference (DSRef) clipboard format. Objects that support DSRef can be dragged-and-dropped onto Visual Studio data designers.
For more information about data object support, see DDEX Data Object Support.
Using a data view support XML file, a DDEX provider defines the physical hierarchy of data objects displayed under a given connection node in the Visual Studio Server Explorer. You can define multiple views for the same data source.
In addition to defining the physical object hierarchy, you can also specify additional information about hierarchy nodes, including such things as localized display name, context menu commands (command name, CLSID, and handler), icons, and other information, as needed.
For more information about data view support, see DDEX Data View Support.
DDEX provides a set of interfaces that are implemented internally as managed classes that Visual Studio calls to access functionality implemented by the DDEX provider in the form of top-level support entities. These interfaces are known collectively as the DDEX core services.
The more important core services include the following:
Provider Manager allows you to enumerate registered DDEX providers and query for objects of a specific type (IVsDataProviderManager interface).
Data Provider Object Factory provides a way to create data objects implemented by the DDEX provider (IVsDataProviderObjectFactory interface).
DDEX core services allow Visual Studio to communicate with data sources in a design-time context. This requires having components that service a connection to the data source as well as having a set of specialized services that provide access to data source object types and views of their hierarchical layouts.
In a typical implementation, a DDEX client calls on the data provider object factory to instantiate the key building blocks. These key building blocks include the connection-building and connection support objects (see the Support Entities and Access Services Diagram). Some of these building-block objects then generate secondary objects, as needed, on down the support entities hierarchy.
DDEX provides a set of interfaces that are implemented internally as managed classes that Visual Studio calls to access functionality for data connection and the in-memory representation of the data object support XML and data view support XML. These interfaces are known collectively as the DDEX access services.
Some of the more important access services include the following:
Data Connection Factory allows you to create connection objects (IVsDataConnectionFactory interface).
Data Connection Dialog allows you to prompt the user for connection information and create connection objects (IVsDataConnectionDialog interface).
You can view the data source connection (and its key pieces, such as the connection manager and connection factory) as an integrated service proffered by the data extensibility framework. In this view, the Visual Studio metadata engine acts like a connection client, consuming Access Services APIs, which in turn call into their corresponding support entities. This is the mechanism through which Visual Studio assembles a support structure to service the connection to the data source.
The main difference between support entities and access services is that extensibility clients consume the access services (primarily the connection object), which in turn communicate with the DDEX provider. Viewed from the opposite direction, providers interact with the connection by using the support entities' APIs.
Under some circumstances, the roles of the access services and the support entities overlap, particularly where it is necessary to ensure thread safety. The DDEX architecture provides a secure locking layer between the data provider and the connection client for this purpose. The following example illustrates the feature.
When you get, for example, the IVsDataCommand service from the connection object, rather than obtaining a data command object, the connection object instead gets a proxy implementation of the IVsDataCommand interface. The proxy implementation communicates with the support entity that implements it; additionally, the proxy implementation is thread-safe. In this way, the proxy first locks the connection and then calls down into the support entities; when finished with the connection, it again unlocks the connection, releasing a thread lock.
In this example, the IVsDataCommand interface is implemented as an access service (in that the client calls it directly), but also behaves as a support entity, in that the data provider implements the same interface, and that the outcome is the creation of a secure locking layer between the provider and the connection client.
The DDEX SDK provides complete language reference documentation:
Use the data object support schema (DataObjectSupport.xsd) to programmatically manage and enumerate instances of data-source objects. For more information about data objects, see DDEX Data Object Support.
Use the data view support schema (DataViewSupport.xsd) to manage one or more views of your data object hierarchy layout as it appears in Server Explorer. For more information about data views, see DDEX Data View Support.