0

I have a multi-project template set up that contains 2 .NET Core projects (ProjA.csproj and UnitTests.csproj). Each is contained within its own folder complete with its own corresponding vstemplate (ProjA.vstemplate and UnitTests.vstemplate, respectively), and I have a root.vstemplate tying them together. The UnitTests project contains a project reference to ProjA. My folder structure looks like this:FolderStructure

I have a vsix installer set up that takes in the zipped contents and everything works great once installed, well almost. I can't figure out how to get the project reference within the UnitTests project renamed to the user specified project name. I've tried $safeprojectname$, but that yields "UnitTests" since it's in the context of that project. I've been through all of the default parameters to no avail. What I need is something like a "masterprojectname". I attempted to use a customParameter (see my Root.vstemplate below), but that didn't work either.

Here is my UnitTests.csproj contents:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>

    <IsPackable>false</IsPackable>

    <RootNamespace>UnitTests</RootNamespace>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
    <PackageReference Include="Moq" Version="4.12.0" />
    <PackageReference Include="nunit" Version="3.12.0" />
    <PackageReference Include="NUnit3TestAdapter" Version="3.11.0" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\ProjA\ProjA.csproj" />
    <!-- I've tried the following but it yields "UnitTests": -->
    <!-- <ProjectReference Include="..\$safeprojectname$\$safeprojectname$.csproj" /> -->
    <!-- Also tried the following with a customParameter in Root.vstemplate, but it didn't work -->
    <!-- <ProjectReference Include="..\$parentproject$\$parentproject$.csproj" /> -->
  </ItemGroup>

</Project>

And here is my UnitTests.vstemplate:

<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
  <TemplateData>
    <Name>UnitTests</Name>
    <Description>Creates a standard UnitsTest project</Description>
    <ProjectType>CSharp</ProjectType>
    <SortOrder>110</SortOrder>
    <CreateNewFolder>true</CreateNewFolder>
    <DefaultName>UnitTests</DefaultName>
    <ProvideDefaultName>true</ProvideDefaultName>
    <LocationField>Enabled</LocationField>
    <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
    <CreateInPlace>true</CreateInPlace>
    <Hidden>true</Hidden>
  </TemplateData>
  <TemplateContent>
    <Project TargetFileName="UnitTests.csproj" File="UnitTests.csproj" ReplaceParameters="true">
      <Folder Name="Business" TargetFolderName="Business">
        <ProjectItem ReplaceParameters="true" TargetFileName="TestsTemplate.cs">TestsTemplate.cs</ProjectItem>
      </Folder>
    </Project>
  </TemplateContent>
</VSTemplate>

And here is my Root.vstemplate:

<VSTemplate Version="3.0.0" Type="ProjectGroup" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
    <TemplateData>
        <Name>MessageListener Template (.NET Core)</Name>
        <Description>Creates a boilerplate MessageListener</Description>
        <ProjectType>CSharp</ProjectType>
        <ProjectSubType>Console</ProjectSubType>
        <SortOrder>10</SortOrder>
        <CreateNewFolder>true</CreateNewFolder>
        <DefaultName>REDACTED</DefaultName>
        <ProvideDefaultName>true</ProvideDefaultName>
        <LocationField>Enabled</LocationField>
        <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
        <Icon>CS.png</Icon>
        <LanguageTag>C#</LanguageTag>
        <PlatformTag>Linux</PlatformTag>
        <PlatformTag>macOS</PlatformTag>
        <PlatformTag>Windows</PlatformTag>
        <ProjectTypeTag>Console</ProjectTypeTag>
    </TemplateData>
    <TemplateContent>
        <ProjectCollection>
            <ProjectTemplateLink ProjectName="$safeprojectname$">
                ProjA\ProjA.vstemplate
            </ProjectTemplateLink>
            <ProjectTemplateLink ProjectName="UnitTests">
                UnitTests\UnitTests.vstemplate
            </ProjectTemplateLink>
        </ProjectCollection>
        <CustomParameters>
          <CustomParameter Name="$parentproject$" Value="$safeprojectname$" />
        </CustomParameters>
    </TemplateContent>
</VSTemplate>
OneRob
  • 1
  • 1

2 Answers2

0

Just wanted to mention I got around this by using the answer provided here.

Basically, I had to use the <ProjectTemplateLink ProjectName="$projectname$.UnitTests" CopyParameters="true"> (note the CopyParameters="true"). Then, in my UnitTests.csproj file, modified the ProjectReference to: <ProjectReference Include="..\$ext_projectname$\$ext_projectname$.csproj" />

The CopyParameters="true" exposes the $ext_projectname$ variable, which contains the project name specified in the "Create a new project dialog", available to the UnitTests project.

OneRob
  • 1
  • 1
0

Check my answer. https://stackoverflow.com/a/65774847/15029912


In short:

See Reserved template parameters - Parameter - ext_* in

Docs - Visual Studio - IDE - Develop - Solutions and projects - Customize templates - Template parameters

Result parameters values from my test:

$safeitemname$ = "Class1"
$safeprojectname$ = "SubProject1"
$ext_safeprojectname$ = "Nested"
$ext_ext_safeprojectname$ = "SolutionName"
Umka
  • 1