繁体   English   中英

如何创建安装最新的NuGet依赖项的项目模板

[英]How to create a project template that installs latest NuGet dependencies

我要创建一个模板,以安装最新版本的NuGet软件包及其所有依赖项。 使用NuGet.VisualStudio.TemplateWizard最常见解决方案NuGet.VisualStudio.TemplateWizard安装指定的程序包版本,并且不解析任何依赖项。 基本上,我想在创建使用模板的项目时运行Install-Package example

如何创建安装最新的NuGet依赖项的项目模板?

显然,您的要求很明确。 但是我们不建议您这样做。 因为更新软件包将破坏模板。

我们知道的是,预安装的软件包可以使用模板向导工作。 实例化模板时,将调用一个特殊的向导。 该向导将加载需要安装的软件包列表,并将该信息传递给适当的NuGet API。

此外,向导中还需要idversion属性,即使有较新的版本,也会用于安装软件包的版本。 这样可以防止程序包更新破坏模板,从而可以选择使用模板将程序包更新给开发人员。

而且,开发人员更新软件包是一件非常简单的事情。 开发人员可以根据自己的要求更新某些软件包,而无需更新所有软件包。

找到2种方法来做到这一点。 新的.csproj标准支持PackageReference指令,以包括NuGet程序包,并支持版本通配符,并且优先使用最高版本。 但这目前IWizard漏洞,因此我最终实现了自己的IWizard ,其功能类似于NuGet的默认向导,但安装了最新的软件包和依赖项:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using EnvDTE;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.TemplateWizard;
using NuGet.VisualStudio;
using Task = System.Threading.Tasks.Task;

namespace Example
{
    public class NuGetTemplateWizard : IWizard
    {
        List<string> _packages;

        public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
        {
            if (customParams.Length > 0) {
                var vstemplate = XDocument.Load((string)customParams[0]);
                _packages = vstemplate.Root
                    .ElementsNoNamespace("WizardData")
                    .ElementsNoNamespace("packages")
                    .ElementsNoNamespace("package")
                    .Select(pkg => pkg.Attribute("id").Value)
                    .ToList();
            }
        }

        public void ProjectFinishedGenerating(Project project)
        {
            Task.Run(delegate {
                var componentModel = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel));
                var _installer = componentModel.GetService<IVsPackageInstaller2>();

                foreach (var package in _packages) {
                    _installer.InstallLatestPackage(null, project, package, false, false);
                }
            });
        }

        public bool ShouldAddProjectItem(string filePath) { return true; }
        public void BeforeOpeningFile(ProjectItem projectItem) { }
        public void ProjectItemFinishedGenerating(ProjectItem projectItem) { }
        public void RunFinished() { }
    }
}

在.vstemplate中:

  <WizardExtension>
    <Assembly>Example, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7a55be3860fb01d1</Assembly>
    <FullClassName>Example.NuGetTemplateWizard</FullClassName>
  </WizardExtension>
  <WizardData>
    <packages>
      <package id="Newtonsoft.Json" />
    </packages>
  </WizardData>

另外我不确定通过Task.Run在后台安装软件包是否安全,但是这种方式响应速度更快,并且所有异步nuget方法都是内部的(不可用)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM