Xamarin与.NET Standard程序集解析机制咨询(含iOS构建失败场景)
Hey there, let's unpack this issue and walk through how assembly resolution works between Xamarin and .NET Standard in your scenario.
First, let's break down why you're hitting that Failed to resolve "System.Buffers.IBufferWriter1"` error when enabling linking on your iOS project, then dive into the underlying resolution system.
What's Causing the Error?
When you enable the Xamarin.iOS Linker, it performs aggressive code trimming to reduce your app's final size—it removes any types, methods, or interfaces it detects as "unused" via static analysis. The problem here is that the AspNetCore SignalR Client uses System.Buffers.IBufferWriter1indirectly (likely via reflection or dynamic interface calls), which the linker can't pick up during its static scan. So it ends up stripping that interface fromSystem.Memory`, even though SignalR needs it at runtime.
How Xamarin & .NET Standard Assembly Resolution Works
Let's walk through the flow specific to your setup:
- .NET Standard Class Library Role: Your class library targets .NET Standard, which is a set of API contracts, not a runtime. When you reference NuGet packages like
AspNetCore SignalR Client, NuGet pulls in the .NET Standard-compatible versions of those packages and their dependencies (likeSystem.Memory). - Xamarin.iOS Runtime Mapping: When your iOS project references the .NET Standard library, Xamarin's build system maps the .NET Standard API contracts to the actual implementation assemblies provided by Xamarin.iOS. For example,
System.Memoryisn't just the .NET Standard version—it's replaced with Xamarin.iOS's own implementation that works on iOS devices. - Build & Linker Pipeline:
- First, the .NET Standard library is compiled to IL (Intermediate Language).
- The iOS project collects all dependent IL assemblies (your library, SignalR Client,
System.Memory, etc.). - The linker runs next: it starts from your app's entry points (like
AppDelegate, your Xamarin.Forms pages) and traces all directly referenced code. Any code not in this trace gets marked for removal. - Finally, the remaining IL is compiled to native iOS code.
The key pain point here is that the linker only sees direct references. If a library uses types dynamically (like SignalR using IBufferWriter1` through interfaces or reflection), the linker doesn't know to keep those types—hence the resolution failure.
Fixing the Error
To resolve this, you need to tell the linker to preserve the missing interface. Here are two common approaches:
1. Use a Linker Description File
Add an XML file (e.g., Linker.xml) to your iOS project, set its Build Action to LinkDescription, and add this content:
<linker> <assembly fullname="System.Memory"> <type fullname="System.Buffers.IBufferWriter`1" preserve="all" /> </assembly> </linker>
This explicitly tells the linker to keep the IBufferWriter1interface and all its members inSystem.Memory`.
2. Adjust Linker Behavior
In your iOS project properties:
- Go to iOS Build > Linker Behavior.
- Switch from
Link All AssembliestoLink Framework SDKs Only. This limits linker trimming to Apple's framework SDKs, leaving your third-party NuGet assemblies (like SignalR Client andSystem.Memory) untouched. Note: This will result in a larger app size, but it's a quick fix to verify the issue is linker-related.
3. Update NuGet Packages
Ensure you're using the latest stable version of AspNetCore SignalR Client—newer versions often include better linker hints or fixes for Xamarin compatibility.
内容的提问来源于stack exchange,提问作者François

