You can extend existing database project types by adding your own features. For example, you can create a feature that does something every time that a database project is loaded or saved. You can also create your own database schema provider and supporting project system. However, that type of extensibility is not covered in this content.
Create a sample project feature: Learn the steps that are required to create a custom project feature that displays a dialog box when a database project is loaded. If you follow these walkthroughs, you will:
Create a Visual Studio package.
Customize that package to create a database project feature.
Build, install, and test your new project feature.
The major goals for the database project extensibility features in Visual Studio 2010 are as follows:
Expose major components through interfaces
This approach keeps the project system consistent with the schema model, by using interfaces instead of abstract classes. A single concrete class is expected to implement many interfaces.
Features are created by the extensibility manager
Features are responsible for major parts of the system including Solution Explorer, Schema View, project upgrade, and project properties.
Features can be extended
Features can use the extensibility manager, XML files, registry or other approaches to provide that extensibility.
Services are exposed through their own interface
DataPackage implements IServiceProvider. Any cross-talk between features should be handled through servicing at these levels. You should not expose your feature as the service. Instead, create a new interface, a wrapper class, and then expose the wrapper as the service.
Events drive the project system
The DataPackage and the ProjectNode() offer events that enable features to drive the project system. In addition, features can provide events through their service interfaces. In some cases, you might decide to use a delegate. To decide which feature handles the action, consider using an event approach where the features could interact, based on priority.
Do not rely on the ordering of listeners
If the order of listeners to an event is important, then consider creating a Pre or Post event or consider adding a priority property to the class derived from EventArg.
Every database project file (.dbproj) contains a property named "DSP" indicating the specific DatabaseSchemaProvider that handles this project when it is opened in Visual Studio. The project system creates an extension manager by using this DSP and from that constructs all the project system contributors and project features. Each feature receives an Initialize event so that it can initialize and root itself into the project system by listening to events.
The following events are raised during project open/close and save:
This event occurs when all services were added and the project has completed opening. However, project will not yet have completed deserializing its previous state. The TaskHost and the DataSchemaModel will be NULL until the ProjectLoaded event is sent.
Every project has one ErrorManager. Some errors are persisted to the .dbmdl file and other errors are not. This is controlled through the AddPersistedCategory class. By default these categories are persisted: ModelCategory, ValidationAtBuildCategory, and ValidationOnIdleCategory. If you add another persisted category you will have to handle the project reload and verify and manage your errors. Remember that although the project was closed, the user could have edited the .dbproj file to remove a file for which you are reporting an error. It would be very confusing to users to report an error in the project when no such file exists.
Database error objects are added to the ErrorManager in specific categories. The idea is that project features can manage the lifetime of their errors through the lifetime of their category. If you are concerned about category names conflicting with other features then use a GUID as the name. The ErrorManager defines several built-in categories including:
This category is designed for you to use for errors whose lifetimes are equal to the lifetime of the project. Therefore, for example, errors which occur during project load are added into this category.