使用Bait+Switch开发的Xamarin.Forms插件在VSTS NuGet Restore时报错求助
I’ve run into this exact issue before when migrating Bait+Switch-style Xamarin plugins to Azure DevOps (formerly VSTS), so let’s break down what’s likely causing this and how to fix it.
Why This Happens
The "Ambiguous project name" error during NuGet Restore usually stems from NuGet detecting multiple projects with identical identifiers (like AssemblyName or solution-level project names) when processing your build. Since Bait+Switch relies on having the bait project (AppUtils.Forms) and platform-specific switch projects (AppUtils.Forms.Android/iOS) share the same AssemblyName for runtime substitution, this can confuse the NuGet Restore task in VSTS—especially if your build configuration uses broad wildcards or has cached old project data.
Step-by-Step Fixes
1. Verify Unique Project Names in Your Solution
First, open your .sln file in a text editor and confirm each project has a distinct ProjectName entry. Even if your AssemblyName values match, the solution-level project names must be unique:
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppUtils.Forms", "AppUtils.Forms\AppUtils.Forms.csproj", "{GUID1}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppUtils.Forms.Android", "AppUtils.Forms.Android\AppUtils.Forms.Android.csproj", "{GUID2}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppUtils.Forms.iOS", "AppUtils.Forms.iOS\AppUtils.Forms.iOS.csproj", "{GUID3}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppUtils.Forms.NuGet", "AppUtils.Forms.NuGet\AppUtils.Forms.NuGet.csproj", "{GUID4}"
If any project names are duplicated here, update them to be unique (this won’t break your Bait+Switch logic since we’re only changing the solution display name).
2. Refine Your VSTS NuGet Restore Task Configuration
Instead of using a broad wildcard like **/*.csproj for your project path, explicitly list the projects you need to restore. This prevents NuGet from picking up conflicting references or ambiguous project identifiers:
- In your VSTS build pipeline, edit the NuGet Restore task.
- Under "Path to solution, packages.config, or project.json", enter:
**/AppUtils.Forms.csproj;**/AppUtils.Forms.Android.csproj;**/AppUtils.Forms.iOS.csproj;**/AppUtils.Forms.NuGet.csproj - Ensure you’re using the latest version of the NuGet tool in the task (under "Advanced" > "NuGet version")—older versions have known issues with handling identical
AssemblyNamevalues across projects.
3. Check Your NuGet Pack Project Configuration
If your AppUtils.Forms.NuGet project uses a .nuspec file, verify the <files> section isn’t accidentally including duplicate assemblies or referencing conflicting project outputs. For example, your nuspec should target the bait project for the base package and platform-specific projects for their respective folders:
<files> <!-- Bait assembly --> <file src="..\AppUtils.Forms\bin\$(Configuration)\AppUtils.Forms.dll" target="lib\netstandard2.0" /> <!-- Android switch assembly --> <file src="..\AppUtils.Forms.Android\bin\$(Configuration)\AppUtils.Forms.dll" target="lib\MonoAndroid12.0" /> <!-- iOS switch assembly --> <file src="..\AppUtils.Forms.iOS\bin\$(Configuration)\AppUtils.Forms.dll" target="lib\xamarinios10" /> </files>
Double-check that you’re not including the same assembly path multiple times, which could trigger the ambiguity error.
4. Clear VSTS Build Cache
Cached build artifacts can sometimes cause leftover references that lead to ambiguity. Add a "Clean" step to your pipeline before the NuGet Restore task:
- Go to your pipeline, click "Add task", search for "Clean".
- Configure it to clean the build directory (default settings should work).
- This ensures you’re starting with a fresh environment for each build.
5. Validate Project AssemblyNames (Last Resort)
While Bait+Switch requires matching AssemblyName values, if the above steps don’t work, temporarily test changing the platform-specific projects’ AssemblyName to something unique (e.g., AppUtils.Forms.Android) to see if the error goes away. If it does, you may need to adjust your NuGet packaging logic to ensure the final package still has the correct assembly names for runtime substitution—though this should be a last resort, as matching AssemblyName is core to Bait+Switch.
Final Notes
I’ve found that explicitly listing projects in the NuGet Restore task and clearing the build cache resolve this issue 9 times out of 10 for Bait+Switch plugins. If you’re still stuck, check the full stack trace for any specific project paths mentioned—this can point you directly to which two projects are causing the ambiguity.
内容的提问来源于stack exchange,提问作者RobVoisey

