parse-community / Parse-SDK-dotNET

Parse SDK for .NET, Xamarin, Unity.
http://parseplatform.org
Apache License 2.0
322 stars 260 forks source link

Preventing initialization exceptions in Xamarin client #358

Open sschaub opened 3 years ago

sschaub commented 3 years ago

Issue Description

Special configuration is required to prevent the following exception from being thrown during ParseClient initialization on Xamarin platform:

Value cannot be null. Parameter name: element

The issue is caused by an assumption encoded into the HostManifestData.Inferred property (Assembly.GetEntryAssembly() is non-null) that is not true on Xamarin. This has been noted in various issues such as #344.

Suggestions

Two suggestions come to mind to improve the situation:

  1. Modify HostManifestData.Inferred so that it populates the Version, Name, and ShortVersion properties with some kind of reasonable default value (empty strings?) if Assembly.GetEntryAssembly() is missing instead of throwing an exception.
  2. Modify HostManifestData.Inferred to throw an exception with a more meaningful error message to help Xamarin users realize that special configuration is needed.
drharris commented 3 years ago

For those running into this, you can get past this issue by initializing using something like the following (the key is to not let it perform lazy initialization on anything that relies on a MetadataController - note the same metadata controller below has been passed into the ServiceHub). There may be other areas you'll need to embed this depending on how your configuration is.

var m = new MetadataMutator
{
      EnvironmentData = new EnvironmentData { TimeZone = TimeZoneInfo.Local.StandardName },
      HostManifestData = new HostManifestData { Name = "Test", Identifier = "TestApp", ShortVersion = "1.0.0.0", Version = "1.0.0.0" }
};
ParseClient client = new ParseClient(new ServerConnectionData
{
       ApplicationID = "APP_ID",
       ServerURI = "SERVER_URI",
       Key = "APP_KEY"
},
new LateInitializedMutableServiceHub { MetadataController=m },
m
);
client.Publicize();