围绕管理您正在使用的 NuGet 版本,您可以使用Directory.Build.targets 为同一解决方案/存储库中的各个项目在一个地方设置共享导入和下游库版本,从而使您的生活更加轻松,因此它们都固定到相同的版本 - 让您更好地控制与 DLL-Hell 等效的 NuGet 依赖项。这是一个很好的参考:https://www.strathweb.com/2018/07/solution-wide-nuget-package-version-handling-with-msbuild-15/
另外,如果它有帮助,我使用此脚本将我的共享项目(位于单独的 repo/sln 中)导入到基于相对路径的相同解决方案中...这让我们可以编写代码并以交互方式调试共享项目主入口点 repos 的上下文。由于重命名同时适用于我的消费库,因此对于共享项目中的快速重构也非常方便。我们不会提交随后受影响的 .Sln / .CSProj 文件。
为了满足您的特定需求,还有很多改进空间,但我们在解决方案旁边转储了一个,称为 Add-CommonAsFramework.ps1 :-)
Param (
[Parameter(Mandatory=$true, Position=1)]
[string] $CommonPath, # Relative path to the common libraries, set up a default if your team has a convention
[Parameter(Mandatory=$true, Position=2)]
[string] $SolutionFile # Try setting the default up "$PSScriptRoot/MySolution.sln"
)
if (-not (Test-Path -Type Leaf $SolutionFile)) {
throw "SolutionFile value does not exist, $SolutionFile is not found"
} else {
$SolutionFile = (Get-Item $SolutionFile).FullName
}
$commonRoot = Get-Item $CommonPath
if (-not (Test-Path $commonRoot)) {
throw "CommonPath value does not exist, $CommonPath is not found"
}
$commonProjects = @(Join-Path $commonRoot.FullName -ChildPath "src/**/*.csproj") # NOTE: Fix for your convention!
$solutionPath = Split-Path -Parent $SolutionFile
Function Get-PackageReferenceNames (
[Parameter(Mandatory=$true, Position = 1)]
[string] $SolutionFile,
[Parameter(Mandatory=$true, Position = 2)]
[string] $ProjectRelativePath
) {
$solutionPath = Split-Path -Parent $SolutionFile
$projectFullPath = Join-Path $solutionPath -ChildPath $ProjectRelativePath
$packageReferencesRaw = dotnet list $projectFullPath package
$packageReferencesRaw -match '^.*>' -replace '^ +> ','' `
| ForEach-Object { $_.split(" ")[0] } `
| Sort-Object -Unique
}
Function Update-PackageReferenceWithProjectReference (
[Parameter(Mandatory=$true, Position = 1)]
[string] $SolutionFile,
[Parameter(Mandatory=$true, Position = 2)]
[string] $ProjectRelativePath,
[Parameter(Mandatory=$true, Position = 3)]
[string] $PackageReferenceName,
[Parameter(Mandatory=$true, Position = 3)]
[string] $ReplaceProjectReferencePath
) {
$solutionPath = Split-Path -Parent $SolutionFile
$projectFullPath = Join-Path $SolutionPath -ChildPath $ProjectRelativePath
dotnet add $projectFullPath reference $ReplaceProjectReferencePath
dotnet remove $projectFullPath package $PackageReferenceName
}
Function Get-ProjectsInSolution (
[Parameter(Mandatory=$true, Position = 1)]
[string] $SolutionFile
) {
# Outputs as a string list, with the first two lines as headers
$projectsListing = & dotnet sln $SolutionFile list
$projectsListing | Select-Object -Skip 2
}
Function Get-RelativePathTo (
[Parameter(Mandatory=$true, Position = 1)]
[string] $relativeTo,
[Parameter(Mandatory=$true, Position = 2)]
[string] $path
) {
if (!(Test-Path $relativeTo)) {
throw "Invalid path $relativeTo"
}
try {
Push-Location $relativeTo
return Get-Item $path | Resolve-Path -Relative
} finally {
Pop-Location
}
}
$tmp = Get-Location
try {
Set-Location $solutionPath
$projects = Get-ProjectsInSolution $SolutionFile
# Test and add Common project to "framework" folder in solution if not already there
$commonProjects `
| Get-Item `
| Where-Object {
$commonProjectRelativeToSolutionPath = Get-RelativePathTo $solutionPath $_.FullName
$projects -notcontains $commonProjectRelativeToSolutionPath
} `
| ForEach-Object {
$commonProjectRelativeToSolutionPath = Get-RelativePathTo $solutionPath $_.FullName
dotnet sln $SolutionFile add --solution-folder "framework" $commonProjectRelativeToSolutionPath
}
$commonProjectNames = @{}
$commonProjects `
| Get-Item `
| ForEach-Object {
$commonProjectRelativeToSolutionPath = Get-RelativePathTo $solutionPath $_.FullName
$commonProjectNames.Add($_.Basename, $commonProjectRelativeToSolutionPath)
}
# Replace any project that references them via NuGet to use the project reference instead
$commonRootRelativeToSolutionPath = Get-RelativePathTo $solutionPath $commonRoot.FullName
$projects `
| Where-Object {
Test-Path (Join-Path $solutionPath $_)
} `
| Where-Object {
# Is not already a Common project
-not $_.StartsWith($commonRootRelativeToSolutionPath)
} `
| ForEach-Object {
$project = $_
$packageReferences = Get-PackageReferenceNames $SolutionFile -ProjectRelativePath $project
$commonPackageReferences = $packageReferences | Where-Object { $commonProjectNames.ContainsKey($_) }
$commonPackageReferences | ForEach-Object {
$commonProjectRelativePath = $commonProjectNames[$_]
Update-PackageReferenceWithProjectReference $SolutionFile -ProjectRelativePath $project -PackageReferenceName $_ -ReplaceProjectReferencePath $commonProjectRelativePath
}
}
} finally {
Set-Location $tmp
}