Visual Studio 模板中的包

创建项目或项时,Visual Studio 项目和项模板通常需要确保安装某些包。 例如,ASP.NET MVC 3 模板安装 jQuery、Modernizr 和其他包。

为了支持此功能,模板作者可以指示 NuGet 安装必要的包,而不是单个库。 然后,开发人员可以在以后轻松更新这些包。

若要详细了解如何创作模板本身,请参阅 如何:创建项目模板创建自定义项目和项模板

本部分的其余部分介绍了创作模板以正确包含 NuGet 包时要采取的具体步骤。

Samples

预安装包示例在 GitHub 上的 NuGet/Samples 存储库中提供。

将包添加到模板

实例化模板时,将调用 模板向导 以加载要安装的包列表以及有关查找这些包的位置的信息。 包可以嵌入到 VSIX 中、嵌入到模板中,或位于本地硬盘驱动器上,在这种情况下,可以使用注册表项来引用文件路径。 本节稍后会提供有关这些位置的详细信息。

预安装的包使用 模板向导工作。 实例化模板时,将调用特殊向导。 向导将加载需要安装的包列表,并将该信息传递给相应的 NuGet API。

在模板中包含包的步骤:

  1. vstemplate文件中,添加WizardExtension元素以引用 NuGet 模板向导:

    <WizardExtension>
        <Assembly>NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
        <FullClassName>NuGet.VisualStudio.TemplateWizard</FullClassName>
    </WizardExtension>
    

    NuGet.VisualStudio.Interop.dll 是一个只包含 TemplateWizard 类的程序集,TemplateWizard 类是一个简单的包装器,用于调用 NuGet.VisualStudio.dll 中的实际实现。 程序集版本永远不会更改,以便项目模板继续与新的 NuGet 版本配合使用。

  2. 添加要安装在项目中的包列表:

    <WizardData>
        <packages>
            <package id="jQuery" version="1.6.2" />
        </packages>
    </WizardData>
    

    向导支持多个 <package> 元素来支持多个包源。 id这两个属性version是必需的,这意味着即使有较新版本可用,也会安装包的特定版本。 这样可以防止包更新破坏模板,留给使用模板的开发人员选择是否更新包。

  3. 指定 NuGet 可在其中找到包的存储库,如以下部分所述。

VSIX 包存储库

建议的 Visual Studio 项目/项模板部署方法是 VSIX 扩展 ,因为它允许你将多个项目/项模板打包在一起,并允许开发人员使用 VS 扩展管理器或 Visual Studio 库轻松发现模板。 使用 Visual Studio 扩展管理器自动更新机制轻松进行扩展的更新部署。

VSIX 本身可以作为模板所需的包的源:

  1. 请按如下步骤修改.vstemplate文件中的<packages>元素:

    <packages repository="extension" repositoryId="MyTemplateContainerExtensionId">
        <!-- ... -->
    </packages>
    

    repository属性指定存储库的类型,而extension是 VSIX 本身的唯一标识符(这是扩展vsixmanifest文件中ID属性的值,请参阅VSIX 扩展架构 2.0 参考)。

  2. nupkg 文件放在 VSIX 中一个名为 Packages 的文件夹里。

  3. vsixmanifest 文件中以 <Asset> 形式添加必要的包文件(请参阅 VSIX 扩展架构 2.0 参考):

    <Asset Type="Moq.4.0.10827.nupkg" d:Source="File" Path="Packages\Moq.4.0.10827.nupkg" d:VsixSubPath="Packages" />
    
  4. 请注意,可以将包传送到项目模板所在的同一 VSIX 中,或者如果这对你的方案更有意义,则可以将它们放在单独的 VSIX 中。 但是,不要引用你没有控制权的任何 VSIX,因为对该扩展的更改可能会破坏模板。

模板包存储库

如果只分发单个项目/项模板,并且不需要将多个模板打包在一起,则可以使用更简单但更有限的方法,直接在项目/项目模板 ZIP 文件中包括包:

  1. .vstemplate文件中修改<packages>元素,如下所示:

    <packages repository="template">
        <!-- ... -->
    </packages>
    

    repository 属性具有值 template ,并且不需要该 repositoryId 属性。

  2. 将包放置在项目/项目模板 ZIP 文件的根文件夹中。

请注意,在包含多个模板的 VSIX 中使用此方法会导致当一个或多个软件包对模板是通用时出现不必要的增大。 在这种情况下,请使用 VSIX 作为存储库, 如上一部分所述。

注册表指定的文件夹路径

使用 MSI 安装的 SDK 可以直接在开发人员的计算机上安装 NuGet 包。 这样,当使用项目或项模板时,它们就立即可用,而无需在此期间提取它们。 ASP.NET 模板使用此方法。

  1. 将 MSI 安装包安装到计算机。 可以只安装 .nupkg 文件,或者可以连同扩展内容一起安装这些文件,这会在使用模板时省去额外步骤。 在这种情况下,请遵循 NuGet 的标准文件夹结构,其中 .nupkg 文件位于根文件夹中,然后每个包都有一个子文件夹,其 ID/版本对作为子文件夹名称。

  2. 编写注册表项以标识包位置:

    • 关键位置:要么在计算机范围内使用 HKEY_LOCAL_MACHINE\SOFTWARE[\Wow6432Node]\NuGet\Repository ,如果是每个用户安装的模板和包,则使用 HKEY_CURRENT_USER\SOFTWARE\NuGet\Repository
    • 密钥名称:使用对您唯一的名称。 例如,用于 VS 2012 的 ASP.NET MVC 4 模板使用 AspNetMvc4VS11
    • 值:包文件夹的完整路径。
  3. 在文件中的 <packages> 元素 .vstemplate 中,添加属性 repository="registry" 并在属性中 keyName 指定注册表项名称。

    • 如果已预先解压缩包,请使用该 isPreunzipped="true" 属性。

    • (NuGet 3.2+) 如果想在包安装完成后强制进行设计时编译,请添加 forceDesignTimeBuild="true" 属性。

    • 作为优化,添加 skipAssemblyReferences="true" 是因为模板本身已经包含必要的引用。

      <packages repository="registry" keyName="AspNetMvc4VS11" isPreunzipped="true">
          <package id="EntityFramework" version="5.0.0" skipAssemblyReferences="true" />
          <-- ... -->
      </packages>
      

最佳做法

  1. 通过在 VSIX 清单中添加对 NuGet VSIX 的引用来声明依赖项:

    <Reference Id="NuPackToolsVsix.Microsoft.67e54e40-0ae3-42c5-a949-fddf5739e7a5" MinVersion="1.7.30402.9028">
        <Name>NuGet Package Manager</Name>
        <MoreInfoUrl>http://dori-uw-1.kuma-moon.com/nuget/</MoreInfoUrl>
    </Reference>
    <!-- ... -->
    
  2. 要求在创建时保存项目/项模板,方法是在<PromptForSaveOnCreation>true</PromptForSaveOnCreation>.vstemplate文件中包含模板。

  3. 模板不包含 packages.config 文件,并且不包含在安装 NuGet 包时添加的任何引用或内容。