Overview of Extensibility for Database Refactoring
You can extend the capabilities of database refactoring to provide new types of refactoring or to refactor new file types. You can implement both types of extensibility for database refactoring by creating feature extensions. Before you create feature extensions for database refactoring, you should understand how the components of database refactoring interact and where you can extend those components.
To enable database refactoring to operate on new targets, you can create custom refactoring contributors by inheriting from the RefactoringContributor abstract base class. For example, you can support refactoring into text files or XML files that are contained in the database project.
To enable new refactoring types that are not included with Visual Studio Team System Database Edition, you can create custom refactoring operations by inheriting from the RefactoringOperation abstract base class. For example, you might implement a new refactoring type to replace nested conditionals with guard clauses in a series of separate IF statements.
The following diagram illustrates how database refactoring uses components known as refactoring contributors to handle specific types of refactoring.
When you apply a database refactoring operation for the first time in your current session of Visual Studio, the refactoring feature is loaded together with all refactoring types and contributors. The command that you specified is passed to the refactoring feature and the specified refactoring type is started. The refactoring contributor manager loops through each contributor that is registered for the specified refactoring type. Each type of contributor applies to a different object or set of objects, and each type can have a different data flow.
When you implement a new type of refactoring, you must create the contributors that are required to support that type of refactoring operation. For example, you might want to create a new refactoring type that replaces nested conditionals with guard clauses. Since that type of refactoring would only change the bodies of procedures or functions, and would not change the names of any database objects, you would only have to create a schema object contributor and a script contributor.
Schema Object Contributors
The following diagram shows the data flow for a refactoring contributor that handles database schema objects.
A schema object contributor updates the definition of a schema object. The contributor updates the Copy On Write Store in the Data Schema Model. The updated IStoreElement is passed to the Script Domain Object Model (Script DOM) Builder and is used to generate an updated Script DOM. The updated Script DOM is compared with the Script DOM of the original definition of that object by the Script DOM Diff Engine, and an updated script is generated.
The following diagram shows the data flow for a reference contributor that handles references between objects.
A reference contributor retrieves all references and their offsets from the Data Schema Model and updates the references in the Copy On Write Store of the Data Schema Model. The updated Script DOM is compared with the original Script DOM, and the results are used to update the scripts that contain the references that were changed.
Data Generation Plans and Database Unit Test Contributors
The following diagram shows the data flow for data generation plans and database unit test contributors.
A contributor for data generation plans uses XPathNavigator to find and update changes in the data generation plan, which is an XML file.
A contributor for database unit tests analyzes the .resx file for the database unit test, and extracts the script strings that are stored in that file. Those script strings are then processed using the same data flow as a database script contributor.
Database Script Contributors
The following diagram shows the data flow for a database script contributor.
A database script contributor handles updates for pre-deployment scripts and post-deployment scripts, for other .sql scripts, and for the SQL script strings extracted from database unit tests. The Model Builder takes the script and builds a model of it in the temporary store of the Data Schema Model. The temporary store is used to create a modified Script DOM model. That modified model is compared with the model from the original script, and the differences are used to generate the final updated script.
You can create your own custom contributors to support additional refactoring targets that were not described earlier in this topic. For example, you can create a custom contributor to update text files, database documentation, or output from third-party tools. You must determine the correct data flow that is required to support the refactoring target. You should reference the types described earlier in this topic if the new target type resembles the target types of an existing contributor.
You can extend a registered type of refactoring to operate on a new target, such as a new type of model element or a new file. To enable refactoring to operate on a new target, you must create new refactoring contributors. The new contributor must be able to operate on one of the defined ContributorInputs for that refactoring type. You create a new refactoring target or contributor by implementing at least one class that inherits from the following base class: