验证解决方案项目之间没有文件引用

时间:2018-12-28 11:26:06

标签: c# .net msbuild solution

假设.NET解决方案中有两个项目:

Solution
    - Project1
    - Project2

我想从Project2到Project1仅拥有Project References,例如:

<ItemGroup>
  <ProjectReference Include="Project1.csproj" />
</ItemGroup>

但是有时开发人员会添加错误的File References,例如:

<ItemGroup>
  <Reference Include="Project1">
    <HintPath>path\to\Project1.dll</HintPath>
  </Reference>
</ItemGroup>

如何确定解决方案项目之间没有File References?理想情况下,这应该是构建错误,但是实现它的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

我找到了解决方案。可以添加MSBuild任务(目标)来检查所有解决方案项目中的文件引用。此任务必须添加到所有项目或Directory.Build.targets中。这是目标:

<Project>
  <Target Name="BeforeBuild">
    <Message Text="Analyzing '$(MSBuildProjectFile)' for file references between solution projects...&#xA;" />

    <GetSolutionProjects Solution="$(MSBuildThisFileDirectory)\YourSolutionName.sln">
      <Output ItemName="Projects" TaskParameter="Output"/>
    </GetSolutionProjects>

    <PropertyGroup>
      <Expression>(@(Projects->'%(ProjectName)', '|')).dll</Expression>
    </PropertyGroup>

    <XmlRead XmlFileName="$(MSBuildProjectFile)" XPath="//Project/ItemGroup/Reference/HintPath">
      <Output ItemName="FileReferences" TaskParameter="Value"/>
    </XmlRead>

    <RegexMatch Input="@(FileReferences)" Expression="$(Expression)">
      <Output TaskParameter="Output" ItemName ="ProjectReferences" />
    </RegexMatch>

    <Error Text="There must be no file references between solution projects, but it was found in '$(MSBuildProjectFile)' to the following file(s): %(ProjectReferences.Identity)"
           Condition="'%(ProjectReferences.Identity)' != ''" />
  </Target>
</Project>

此目标使用MSBuild Community Tasks,因此请不要忘记将此NuGet包添加到您的所有项目(或Directory.Build.props)中。

答案 1 :(得分:0)

您可以编写一个简单的PowerShell

$path = "D:\temp\Solution1"
$extension = "csproj"


#-------------------

$projects = Get-ChildItem -Path $path -Recurse -Filter "*.$($extension)"

$projectsList = @()

# Create the project's solution list
foreach ($project in $projects)
{
    $projectsList += $project
}


foreach($project in $projectsList)
{   
    # Read the project xml
    [xml]$proj = [System.IO.File]::ReadAllText($project.FullName)

    # loop throught ItemGroup
    foreach($item in $proj.Project.ItemGroup)
    {

        # Looking for project reference
        $all = $projectsList | where {$_.Name -eq "$($item.Reference.Include).$($extension)"} 

        foreach($ref in $all)
        {
            Write-Warning "Find wrong reference for $($ref.Name) on $($project.Name)"
        }
    }

}