问题
In my Xamarin.iOS project I need to reduce the assembly size (Apple's requirement for AppStore applications), and I need to turn on linker, setting the linker behavior either to "Link Framework SDKs only" or "Link All".
When I've selected "Link Framework SDKs only" in Linker behavior I get the compilation error upon building the project:
Can't resolve the reference 'System.Void System.Data.SqlClient.SqlCommandBuilder::DeriveParameters(System.Data.SqlClient.SqlCommand)', referenced from the method 'System.Void DevExpress.Xpo.DB.MSSqlConnectionProvider::CommandBuilderDeriveParameters(System.Data.IDbCommand)' in 'System.Data.SqlClient, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
To fix this issue all answers I have found recommendation to turn "Link All" option in the Linker behavior option.
When I've selected "Link All", the project compiles okay, but at the runtime I get system exception on the IoC Container code (type AAA
does not implement the interface BBB
), because I use reflection, and linker with "Link All" options affects the code with the reflection. And as far as I know this linker option (Link All) is not recommended for the projects where reflection is being used.
What options do I have at this point?
回答1:
Linker configuration
I suspect your best option is to look at define a configuration file to tell the Linker what must be kept. There is a good set of documentation on Microsofts documentation site.
There are some other options but may not strictly apply in this case or you may wish to use a combination.
Preserve Attribute
You can provide extra definitions to the linker to ensure the type, methods and/or fields are not eliminated from your application. In your own code the preferred way is to use the [Preserve] custom attribute, as discussed in the Linking on iOS and Linking on Android guides.
Linking for each platform is certainly a possibility however I suspect that you want to preserve things in your shared project which is why I think the config file will be right for you.
This approach gives you the ability to define at varying levels (e.g. assembly or class level to keep everything or down to individual properties/methods, etc.).
Actually reference the bits you need kept
I dislike this option very much but some people find it quick and easy to either prove you can keep parts of the code or just accept it is a solution.
You essentially create a class of actual references to the methods/properties that you want to be kept.
public class LinkerPleaseInclude
{
public void Include(MyType arg)
{
arg.MethodIDontWantRemoved();
}
}
Note I have sourced some details from this site
来源:https://stackoverflow.com/questions/65142885/xamarin-ios-linker-and-reflection-issue