AutoMapper Mapper.Initialize causing ArgumentNullException in System.Linq.Expressions (Xamarin.iOS)

Viewed 992

I am trying to integrate AutoMapper into my Xamarin Forms application. It successfully works in Android both device and simulator but in iOS I can only get it to work in the simulator. Running it on a real device cause System.ArgumentNullException.

Here is my Mapper.Initialize code that is in my App.xaml.cs OnStart method:

// AutoMapper config
Mapper.Initialize(cfg =>
{
    cfg.AddProfile<MappingProfile>();
});

Here is the stack trace:

System.ArgumentNullException: Value cannot be null.
Parameter name: method
  at System.Linq.Expressions.Expression.Call (System.Reflection.MethodInfo method, System.Linq.Expressions.Expression arg0) [0x0003e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.0.0.0/src/mono/external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/MethodCallExpression.cs:879
  at AutoMapper.Mappers.ConvertMapper.ConvertExpression (System.Type sourceType, System.Type destinationType) [0x00040] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at AutoMapper.Mappers.ConvertMapper+<>c__DisplayClass1_1.<GetConverters>b__4 () [0x00000] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at System.Lazy`1[T].CreateValue () [0x00081] in <6314851f133e4e74a2e96356deaa0c6c>:0
  at System.Lazy`1[T].LazyInitValue () [0x0000c] in <6314851f133e4e74a2e96356deaa0c6c>:0
  at System.Lazy`1[T].get_Value () [0x0003a] in <6314851f133e4e74a2e96356deaa0c6c>:0
  at AutoMapper.Mappers.ConvertMapper.MapExpression (AutoMapper.IConfigurationProvider configurationProvider, AutoMapper.ProfileMap profileMap, AutoMapper.PropertyMap propertyMap, System.Linq.Expressions.Expression sourceExpression, System.Linq.Expressions.Expression destExpression, System.Linq.Expressions.Expression contextExpression) [0x00021] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at AutoMapper.Execution.TypeMapPlanBuilder.ObjectMapperExpression (AutoMapper.IConfigurationProvider configurationProvider, AutoMapper.ProfileMap profileMap, AutoMapper.TypePair typePair, System.Linq.Expressions.Expression sourceParameter, System.Linq.Expressions.Expression contextParameter, AutoMapper.PropertyMap propertyMap, System.Linq.Expressions.Expression destinationParameter) [0x0000b] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at AutoMapper.Execution.TypeMapPlanBuilder.MapExpression (AutoMapper.IConfigurationProvider configurationProvider, AutoMapper.ProfileMap profileMap, AutoMapper.TypePair typePair, System.Linq.Expressions.Expression sourceParameter, System.Linq.Expressions.Expression contextParameter, AutoMapper.PropertyMap propertyMap, System.Linq.Expressions.Expression destinationParameter) [0x0006d] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at AutoMapper.Execution.TypeMapPlanBuilder.MapExpression (AutoMapper.TypePair typePair, System.Linq.Expressions.Expression sourceParameter, AutoMapper.PropertyMap propertyMap, System.Linq.Expressions.Expression destinationParameter) [0x00011] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at AutoMapper.Execution.TypeMapPlanBuilder.CreatePropertyMapFunc (AutoMapper.PropertyMap propertyMap, System.Linq.Expressions.Expression destination) [0x000de] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at AutoMapper.Execution.TypeMapPlanBuilder.CreatePropertyMapFunc (AutoMapper.PropertyMap propertyMap) [0x00000] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at AutoMapper.Execution.TypeMapPlanBuilder.TryPropertyMap (AutoMapper.PropertyMap propertyMap) [0x00000] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at AutoMapper.Execution.TypeMapPlanBuilder.CreateAssignmentFunc (System.Linq.Expressions.Expression destinationFunc, System.Boolean constructorMapping) [0x00044] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at AutoMapper.Execution.TypeMapPlanBuilder.CreateMapperLambda (System.Collections.Generic.HashSet`1[T] visitedTypeMaps) [0x000bb] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at AutoMapper.TypeMap.Seal (AutoMapper.IConfigurationProvider configurationProvider, System.Collections.Generic.HashSet`1[T] visitedTypeMaps) [0x00088] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at AutoMapper.MapperConfiguration.Seal () [0x001f8] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at AutoMapper.MapperConfiguration..ctor (AutoMapper.Configuration.MapperConfigurationExpression configurationExpression) [0x00177] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at AutoMapper.MapperConfiguration..ctor (System.Action`1[T] configure) [0x00007] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at AutoMapper.Mapper.Initialize (System.Action`1[T] config) [0x00000] in <0cc4ddabcc77416ea712cf2d35abef51>:0
  at Mobile.App.OnStart () [0x0002c]

I have ensured that Xcode, NuGet packages and Visual Studio are all up to date.

Any help appreciated!

2 Answers

The answer is that you need to include a LinkDescription.xml in the root inside your project with build settings set to LinkDescription and the following content:

<linker> 
  <assembly fullname="mscorlib">
    <type fullname="System.Convert" preserve="All" />
  </assembly>
</linker>

Side note: I've tried to add this line to the Additional mtouch arguments --linkskip System.Convert as described on https://docs.microsoft.com/en-us/xamarin/ios/deploy-test/linker but it did not work.

Only the LinkDescription.xml worked. A reference on how the LinkDescription.xml works can be found here: https://docs.microsoft.com/en-us/learn/modules/prepare-to-publish-your-xamarin-application/5-preserve-critical-code

There is also a closed issue on GitHub for this problem which suggests the same solution: https://github.com/AutoMapper/AutoMapper/issues/2272

Right click on iOS project > property > set Linker Behavior to Don't Link

Right click on iOS project > property > set Linker Behavior to Don't Link

Related