【问题标题】:How to use extern alias with nuget如何在 nuget 中使用外部别名
【发布时间】:2015-11-01 09:09:25
【问题描述】:

我在我的项目中使用extern alias,因此我需要将引用别名从global 更改为其他名称。问题是,如果我使用 Nuget 添加引用,则每次更新包时,别名都会恢复为 global。有没有办法阻止这种情况发生?

【问题讨论】:

    标签: c# nuget


    【解决方案1】:

    这是 nuget 引用的已知问题;如果完全不支持程序集别名(目前):https://github.com/NuGet/Home/issues/4989

    幸运的是存在解决方法;您可以向您的 csproj 添加特殊目标,以便即时分配别名:

      <Target Name="ChangeAliasesOfNugetRefs" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
        <ItemGroup>
          <ReferencePath Condition="'%(FileName)' == 'CoreCompat.System.Drawing'">
            <Aliases>CoreCompatSystemDrawing</Aliases>
          </ReferencePath>
        </ItemGroup>
      </Target>
    

    【讨论】:

    • 考虑到这个问题,这可能很明显,但您在 .cs 文件中的所有用法上都使用extern alias CoreCompatSystemDrawing; 引用它。
    • 你救了我;这正是我遇到问题的图书馆。谢谢。
    • 现在从 NuGet 5.7 开始支持:docs.microsoft.com/en-us/nuget/release-notes/nuget-5.7
    • 我希望我能投票 100000 次。这让我在一个旧项目上发疯了
    • 我仍然收到错误 The extern alias 'CoreCompatSystemDrawing' is not specified in a /reference option
    【解决方案2】:

    感谢 csproj Target 更改程序集引用的别名。

    我用它来修复 System.Data.Services.Client/Microsoft.Data.Services.Client 冲突,像这样:

    错误 CS0433:“DataServiceContext”类型存在于两者中 'Microsoft.Data.Services.Client,版本=5.8.3.0,文化=中性, PublicKeyToken=31bf3856ad364e35' 和 'System.Data.Services.Client, 版本=4.0.0.0,文化=中性,PublicKeyToken=b77a5c561934e089'

    解决办法是:

      <!--
      Avoid collision of older System.Data.Services.Client with newer Microsoft.Data.Services.Client
      when mixed due to PackageReferences
      -->
      <Target Name="ChangeAliasesOfNugetRefs" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
        <ItemGroup>
          <ReferencePath Condition="'%(FileName)' == 'System.Data.Services.Client'">
            <Aliases>legacy</Aliases>
          </ReferencePath>
        </ItemGroup>
      </Target>
    

    【讨论】:

      【解决方案3】:

      从 NuGet 5.7 和 Visual Studio 2019 Update 7 开始,PackageReference 现在是 supports the Aliases property。没有UI,但是可以直接编辑项目文件:

      <ItemGroup>
          <PackageReference Include="NuGet.Versioning" Version="5.8.0" Aliases="ExampleAlias" />
      </ItemGroup>
      

      然后在C#代码中:

      extern alias ExampleAlias;
      
      namespace PackageReferenceAliasesExample
      {
      ...
              {
                  var version = ExampleAlias.NuGet.Versioning.NuGetVersion.Parse("5.0.0");
                  Console.WriteLine($"Version : {version}");
              }
      ...
      }
      

      【讨论】:

        【解决方案4】:

        这是不可能的,因为在 nuget update 之后,它会删除以前的程序集并添加一个新程序集,因此它会删除带有别名的程序集......所以您必须再次将别名添加到新的更新程序集。

        【讨论】:

        【解决方案5】:

        您可以在 NuGet 包中添加 install script 以添加别名。但是包的消费者不能选择不添加别名。这是您可以在脚本中使用的一些代码。我不是最擅长 powershell 的,所以可能有更好的方法来做到这一点:)

        # Standard Install.ps1 parameter list
        param($installPath, $toolsPath, $package, $project)
        
        # Name of the alias
        $alias = 'MyAlias'
        
        # Load the Microsoft.Build assembly to be able to access MS Build types
        Add-Type -AssemblyName Microsoft.Build
        
        # Load the csproj file
        $projectObject = New-Object Microsoft.Build.Evaluation.Project($project.FullName)
        
        # Search through the project items to find all references
        $referenceItems = $projectObject.Items | where ItemType -eq "Reference" 
        
        # Find the reference that matches the package id 
        # (this assumes your assembly name matches your package id)
        $item = $referenceItems | select @{Name='Reference'; Expression={$_}},@{Name='AssemblyName'; Expression={(New-Object System.Reflection.AssemblyName($_.UnevaluatedInclude)).Name}} | where AssemblyName -eq $package.Id | select Reference
        
        # If the reference doesnt already have an alias, add one and save the project
        if (($item.Reference.Metadata | where Name -eq 'Aliases') -eq $null) {
            $item.Reference.SetMetadataValue('Aliases', $alias)
            $projectObject.Save()
        }
        
        # Unload the project when done
        $projectObject.ProjectCollection.UnloadAllProjects()
        

        【讨论】:

          猜你喜欢
          • 2017-08-19
          • 2011-11-29
          • 2016-06-24
          • 2018-03-29
          • 1970-01-01
          • 2021-05-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多