How to: Implement nested projects

Applies to: yesVisual Studio noVisual Studio for Mac

Note

This article applies to Visual Studio 2017. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here

When you create a nested project type, there are several additional steps that must be implemented. A parent project takes on some of the same responsibilities that the solution has for its nested (child) projects. The parent project is a container of projects similar to a solution. In particular, there are several events that must be raised by the solution and by the parent projects to build the hierarchy of nested projects. These events are described in the following process for creating nested projects.

Create nested projects

  1. The integrated development environment (IDE) loads the parent project's project file and startup information by calling the IVsProjectFactory interface. The parent project is created and added to the solution.

    Note

    At this point, it is too early in the process for the parent project to create the nested project because the parent project must be created before the child projects can be created. Following this sequence, the parent project can apply settings to the child projects and the child projects can acquire information from the parent projects if needed. This sequence is if it is needed on by clients such as source code control (SCC) and Solution Explorer.

    The parent project must wait for the OpenChildren method to be called by the IDE before it can create its nested (child) project or projects.

  2. The IDE calls QueryInterface on the parent project for IVsParentProject. If this call succeeds, the IDE calls the OpenChildren method of the parent to open all of the nested projects for the parent project.

  3. The parent project calls the FireOnBeforeOpeningChildren method to notify listeners that nested projects are about to be created. SCC, for example, is listening to those events to know if the steps in the solution and project creation process are occurring in order. If the steps occur out of order, the solution might not be registered with source code control correctly.

  4. The parent project calls AddVirtualProject method or the AddVirtualProjectEx method on each of its child projects.

    You pass __VSADDVPFLAGS to the AddVirtualProject method to indicate that the virtual (nested) project should be added to the project window, excluded from the build, added to source code control, and so on. VSADDVPFLAGS lets you control the visibility of the nested project and indicate what functionality is associated with it.

    If you reload a previously existing child project that has a project GUID stored in the parent project's project file, the parent project calls AddVirtualProjectEx. The only difference between AddVirtualProject and AddVirtualProjectEX is that AddVirtualProjectEX has a parameter to enable the parent project to specify a per instance guidProjectID for the child project to enable GetProjectOfGuid and GetProjectOfProjref to function correctly.

    If there is no GUID available, such as when you add a new nested project, the solution creates one for the project at the time it is added to the parent. It is the responsibility of the parent project to persist that project GUID in its project file. If you delete a nested project, the GUID for that project can also be deleted.

  5. The IDE calls the OpenChildren() method on each child project of the parent project.

    The parent project must implement IVsParentProject if you want to nest projects. But the parent project never calls QueryInterface for IVsParentProject even if it has parent projects underneath it. The solution handles the call to IVsParentProject and, if it is implemented, calls OpenChildren to create the nested projects. AddVirtualProjectEX is always called from OpenChildren. It should never be called by the parent project to keep the hierarchy creation events in order.

  6. The IDE calls the OnAfterOpenProject method on the child project.

  7. The parent project calls the FireOnAfterOpeningChildren method to notify listeners that the child projects for the parent have been created.

  8. The IDE calls the FireOnAfterOpenProject method on the parent project after all child projects have been opened.

    If it does not already exist, the parent project creates a GUID for each nested project by calling CoCreateGuid.

    Note

    CoCreateGuid is a COM API called when a GUID is to be created. For more information, see CoCreateGuid and GUIDs in the MSDN Library.

    The parent project stores this GUID in its project file to be retrieved the next time that it is opened in the IDE. See step 4 for more information relating to the calling of AddVirtualProjectEX to retrieve the guidProjectID for the child project.

  9. The GetProperty method is then called for the parent ItemID that by convention you delegate in to the nested project. The GetProperty retrieves the properties of the node that nests a project that you want to delegate in when it is called on the parent.

    Because parent and child projects are instantiated programmatically, you can set properties for nested projects at this point.

    Note

    Not only do you receive the context information from the nested project, but you can also ask if the parent project has any context for that item by checking __VSHPROPID.VSHPROPID_UserContext. In that way, you can add extra dynamic help attributes and menu options specific to individual nested projects.

  10. The hierarchy is built for display in Solution Explorer with a call to the GetNestedHierarchy method.

    You pass the hierarchy to the environment through GetNestedHierarchy to build the hierarchy for display in Solution Explorer. In this manner, the solution knows that the project exists and can be managed for building by the build manager, or can allow files in the project to be put under source code control.

  11. When all the nested projects for Project1 have been created, control is passed back to the solution and the process is repeated for Project2.

    This same process for creating nested projects occurs for a child project that has a child. In this case, if BuildProject1, which is a child of Project1, had child projects, they would be created after BuildProject1 and before Project2. The process is recursive and the hierarchy is built from the top down.

    When a nested project is closed because the user closed the solution or the specific project itself, the other method on IVsParentProject, CloseChildren, is called. The parent project wraps calls to the RemoveVirtualProject method with the OnBeforeClosingChildren and the OnAfterClosingChildren methods to notify listeners to solution events that the nested projects are being closed.

The following topics deal with several other concepts to consider when you implement nested projects:

See also