Problems
- In Release mode, .NET MAUI / Xamarin iOS and Android apps that use XPO for data access can crash with TypeLoadException or MissingMethodException if you build with one of the following linker options:
- Link Framework SDKs Only (iOS)
- Sdk Assemblies Only (Android)
- Link All (iOS and Android)
- .NET MAUI / Xamarin iOS apps built using the AOT compilation can crash with System.ExecutionEngineException. The exception message can be as follows: *Attempting to JIT compile method '(wrapper delegate-invoke) void <Module>:invoke_callvirt_void_SqliteParameter_SqliteType (Microsoft.Data.Sqlite.SqliteParameter,Microsoft.Data.Sqlite.SqliteType)' while running in aot-only mode. *.
- When the Linker Behavior is set to Link All, the MonoTouch linker does not preserve classes or properties that you do not use in code. This behavior can lead to issues with XPO classes if you use their properties only for reading and never for writing. In this situation, the linker preserves only the
get_XXX
methods. So, such properties become read-only, and XPO cannot assign their values.
Solutions for #1
Sometimes the .NET MAUI / Xamarin linker cannot detect that your apps use specific assemblies, classes, or methods via Reflection. XPO uses Reflection to support multiple database providers and calls their methods without direct assembly references. The Xamarin linker can treat these methods as unused and remove them to optimize package size. For more information, see: Linking Xamarin.iOS Apps | Linking on Android.
Option #1 (Simple)
Set Linking to None. APK size: 74164 KB.
Option #2
Set Linking to Sdk and User Assemblies and skip the following assemblies:
- DevExpress.Data and DevExpress.Xpo.
- Database provider assemblies (see Database Systems Supported by XPO or database documentation for exact assembly names).
Android:
Under the Android Options section in the Project Properties, write assembly names in the Skip linking assemblies field as semicolon-separated strings:
DevExpress.Data.vXX.X; DevExpress.Xpo.vXX.X
iOS:
Under the iOS Build section in Project Properties, type the following in the Additional mtouch arguments field:
--linkskip=DevExpress.Data.vXX.X --linkskip=DevExpress.Xpo.vXX.X --linkskip=YourDatabaseProviderAssemblyName
Replace X
with the version number, for instance, DevExpress.Data.v20.1
. APK size: 29677 KB.
Option #3 (Advanced)
Add the Custom Linker Configuration files for the DevExpress, database provider and other required assemblies. APK size: 25063 KB.
DevExpress.Xpo and DevExpress.Data assemblies
XML<?xml version="1.0" encoding="utf-8" ?>
<linker>
<assembly fullname="DevExpress.Xpo.v20.1">
<type fullname="DevExpress.Xpo.DB.Helpers*" />
</assembly>
<assembly fullname="DevExpress.Data.v20.1">
<type fullname="DevExpress.Xpo.DB.Helpers*" />
</assembly>
</linker>
Database provider assemblies
The configuration file should include the following types:
- The connection class (implements the IDbConnection interface)
- The command class (implements the IDbCommand interface)
- The parameter class (implements the IDbDataParameter interface)
- The exception class (for example, SqlException)
Other required assemblies
If the application still raises TypeLoadException or MissingMethodException, exception details contain full type names - add these types to the configuration file. A sample configuration file for the System.Data.SqlClient assembly:
XML<?xml version="1.0" encoding="utf-8" ?>
<linker>
<assembly fullname="System.Data.SqlClient">
<type fullname="System.Data.SqlClient.SqlConnection" />
<type fullname="System.Data.SqlClient.SqlParameter" />
<type fullname="System.Data.SqlClient.SqlException" />
<type fullname="System.Data.SqlClient.SqlError" />
<type fullname="System.Data.SqlClient.SqlCommand" />
<type fullname="System.Data.SqlClient.SqlCommandBuilder" />
</assembly>
</linker>
Solutions for #2
This error can occur when XPO uses the SetType query parameter mode. For performance reasons, we cannot use reflection when dealing with provider-specific parameter types. To implement the new query parameter mode, we need to compile delegates dynamically. Xamarin.Mac ahead of time compilation does not support this approach - Limitations of Xamarin.iOS - No Dynamic Code Generation.
In Xamarin, we recommend setting the static ConnectionProviderSql.GlobalQueryParameterMode field to QueryParameterMode.Legacy.
Solutions for # 3
- Decorate an assembly containing XPO classes with the Preserve attribute. This attribute prevents the MonoTouch linker from linking the target. See also: Set assembly attributes.
- Decorate each XPO class with the Preserve attribute.
- Use Custom Linker Configuration to make sure that your XPO classes are not eliminated from your application.