How to: Implement nested projects
Applies to: Visual Studio Visual 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
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.
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.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.
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 betweenAddVirtualProject
andAddVirtualProjectEX
is thatAddVirtualProjectEX
has a parameter to enable the parent project to specify a per instanceguidProjectID
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.
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 callsQueryInterface
forIVsParentProject
even if it has parent projects underneath it. The solution handles the call toIVsParentProject
and, if it is implemented, callsOpenChildren
to create the nested projects.AddVirtualProjectEX
is always called fromOpenChildren
. It should never be called by the parent project to keep the hierarchy creation events in order.The IDE calls the OnAfterOpenProject method on the child project.
The parent project calls the FireOnAfterOpeningChildren method to notify listeners that the child projects for the parent have been created.
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, seeCoCreateGuid
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 theguidProjectID
for the child project.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.
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.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:
- Considerations for unloading and reloading nested projects
- Wizard support for nested projects
- Implement command handling for nested projects
- Filter the AddItem dialog box for nested projects