MvvmCross Xamarin Android Linking Issue With SerilogLogProvider
Running into Linker issue again with MvvmCross in Xamarin Android. Recently upgraded to MvvmCross 6.1.2 and started using Serilog. When compile in release mode with “Sdk and User Assemblies”, I got the following error from base.CreateLogProvider() during Android Setup:
The CreateLogProvider() code:
public override MvxLogProviderType GetDefaultLogProviderType()
=> MvxLogProviderType.Serilog;
protected override IMvxLogProvider CreateLogProvider()
{
Serilog.Log.Logger = new LoggerConfiguration()
.MinimumLevel.Error()
.WriteTo.AndroidLog()
.CreateLogger();
return base.CreateLogProvider();
}
EXCEPTION:
System.Exception: HandleAndroidException ---> System.ArgumentNullException: Value cannot be null.
Parameter name: method
at System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression instance, System.Reflection.MethodInfo method, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1, System.Linq.Expressions.Expression arg2)[0x0009d] in <c674d6912966428cb26998a802347469>:0
at System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression instance, System.Reflection.MethodInfo method, System.Collections.Generic.IEnumerable`1[T] arguments) [0x00074] in <c674d6912966428cb26998a802347469>:0
at System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression instance, System.Reflection.MethodInfo method, System.Linq.Expressions.Expression[] arguments) [0x00000] in <c674d6912966428cb26998a802347469>:0
at MvvmCross.Logging.LogProviders.SerilogLogProvider.GetForContextMethodCall() [0x00086] in <df54a54dac96467098c3a9eece96a79b>:0
at MvvmCross.Logging.LogProviders.SerilogLogProvider..ctor() [0x00018] in <df54a54dac96467098c3a9eece96a79b>:0
at MvvmCross.Core.MvxSetup.CreateLogProvider() [0x00045] in <df54a54dac96467098c3a9eece96a79b>:0
at myRouteTracker.Droid.Setup.CreateLogProvider() [0x0002a] in <bdd41c7f90344b17a5e6bc21c3959feb>:0
at MvvmCross.Core.MvxSetup.InitializeLoggingServices() [0x00000] in <df54a54dac96467098c3a9eece96a79b>:0
at MvvmCross.Core.MvxSetup.InitializePrimary() [0x00016] in <df54a54dac96467098c3a9eece96a79b>:0
at MvvmCross.Core.MvxSetupSingleton.StartSetupInitialization() [0x0000a] in <df54a54dac96467098c3a9eece96a79b>:0
at MvvmCross.Core.MvxSetupSingleton.InitializeAndMonitor(MvvmCross.Core.IMvxSetupMonitor setupMonitor) [0x00042] in <df54a54dac96467098c3a9eece96a79b>:0
at MvvmCross.Droid.Support.V7.AppCompat.MvxSplashScreenAppCompatActivity.OnCreate(Android.OS.Bundle bundle) [0x00019] in <2d476ccd46884988a021d78ffc7a2843>:0
at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_(System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x0000f] in <1b4c73c9a2864ea8b5827f31fda08c32>:0
at(wrapper dynamic-method) System.Object.e043741f-fba6-4072-a6c2-cfc97949a294(intptr, intptr, intptr)
--- End of inner exception stack trace ---
With other linking issues, I usually try to access the function being stripped out in LinkerPleaseInclude. i.e. MvvmCross.Logging.LogProviders.SerilogLogProvider.GetForContextMethodCall() in this case. However, SerilogLogProvider is an internal class that I could not access.
The last thing I tried is to add Serilog and MvvmCross.Logging.LogProviders to “Skip linking assemblies”. It does not work neither.
Thank you very much for your help in advance.
Regards,
Nick
Answer
The issue is that SerilogLogProvider
uses reflection against Serilog.dll
(See GitHub SerilogLogProvider
source). Even if you had access to the SerilogLogProvider
class it would not help in preventing the linker from stripping away the needed methods. The reason being is that the linker is actually stripping the methods that you need from the Serilog.dll
.
You can add the following include to your LinkerPleaseInclude.cs
to prevent the linker from stripping out the methods that SerilogLogProvider
makes use of.
public void Include(Serilog.ILogger logger)
{
Serilog.Events.LogEventLevel logEventLevel = Serilog.Events.LogEventLevel.Debug;
_ = Serilog.Log.ForContext("", "", false);
_ = Serilog.Context.LogContext.PushProperty("", "", false);
_ = !logger.IsEnabled(logEventLevel);
logger.Write(logEventLevel, "", new object[0]);
logger.Write(logEventLevel, new Exception(), "", new object[0]);
}
Related Questions
- → How to Fire Resize event after all images resize
- → JavaScript in MVC 5 not being read?
- → URL routing requires /Home/Page?page=1 instead of /Home/Page/1
- → Getting right encoding from HTTPContext
- → How to create a site map using DNN and C#
- → I want integrate shopify into my mvc 4 c# application
- → Bootstrap Nav Collapse via Data Attributes Not Working
- → Shopify api updating variants returned error
- → Get last n quarters in JavaScript
- → ASP.NET C# SEO for each product on detail page on my ECOMMERCE site
- → SEO Meta Tags From Behind Code - C#
- → onchange display GridView record if exist from database using Javascript
- → How to implement search with two terms for a collection?