在运行时使用NuGet.PackageManagement,使用户能够安装软件包(从私人仓库中),其中软件包将由System.Runtime.Loader.AssemblyLoadContext
加载并执行。
install方法使用NuGetPackageManager
和NuGetProject
,它们是根据NuGet.Client
可以理解的方式适当设置的
_nugetProject
是扩展FolderNuGetProject
的实例,该实例将软件包存储在指定的文件夹中,而GetInstalledPackagesAsync
返回已安装软件包的列表,而不是空列表。
_packageManager
是NuGetPackageManager
,而_packageRepository
是SourceRepositoryProvider
,都是默认实例,带有适当的路径和源存储库。
public async Task InstallPackageAsync(string packageId, SemanticVersion packageVersion, CancellationToken cancellationToken = default)
{
var packageIdentity = new PackageIdentity(packageId, new NuGetVersion(packageVersion.ToNormalizedString()));
using (var sourceCache = new SourceCacheContext()) {
var resolutionContext = new ResolutionContext(
DependencyBehavior.Highest,
includePrelease: true,
includeUnlisted: true,
VersionConstraints.None,
new GatherCache(),
sourceCache);
var projectContext = new EmptyNuGetProjectContext()
{
PackageExtractionContext = new PackageExtractionContext(
PackageSaveMode.Defaultv3,
XmlDocFileSaveMode.Skip,
ClientPolicyContext.GetClientPolicy(_nugetSettings, _nugetLogger),
_nugetLogger),
ActionType = NuGetActionType.Install,
};
var previewActions = await _packageManager.PreviewInstallPackageAsync(
_nugetProject,
packageIdentity,
resolutionContext,
projectContext,
_packageRepository.GetPrimaryRepositories().ToList(),
_packageRepository.GetRepositories().ToList(),
cancellationToken);
// List all actions in debug log.
var debugOutput = new StringBuilder();
debugOutput.AppendLine($"Install actions for {packageId}:");
foreach(var action in previewActions)
debugOutput.AppendLine($" - {action.NuGetProjectActionType}: {action.PackageIdentity}");
_logger.LogDebug(debugOutput.ToString());
await _packageManager.ExecuteNuGetProjectActionsAsync(
_nugetProject,
previewActions,
projectContext,
sourceCache,
cancellationToken);
}
}
目标是获取已安装的特定程序包的依赖关系图,并使用该信息来加载程序集及其必需的依赖关系。
困难之处在于无法找到已经存在的相关API。鉴于这是Visual Studio中非常常见的任务,因此假定NuGet将提供一种构建依赖关系图的方法。
有await _nugetProject.GetInstalledPackagesAsync(cancellationToken)
,但是仅返回PackageReference
的列表,其中仅包含VersionRange
和PackageId
。
注意:NuGet.Client已作为如何正确使用NuGet API的参考