rdavisau/essential-interfaces

deviceDisplay.MainDisplayInfo = 'deviceDisplay.MainDisplayInfo' threw an exception of type 'Xamarin.Essentials.NotImplementedInReferenceAssemblyException'

Closed this issue · 3 comments

Hi there,

First of all thanks for making this nuget available. Im just having an issue though with the IDeviceDisplay and calling the MainDisplayInfo. In my app in the App.cs class I am checking the device main display info and the exception being raised is:

deviceDisplay.MainDisplayInfo = 'deviceDisplay.MainDisplayInfo' threw an exception of type 'Xamarin.Essentials.NotImplementedInReferenceAssemblyException'

Would this be because I'm running unit tests without on an actual device and there is simply no implementation of it therefore?

I actually Registered the service prior to calling it using FreshMVVM i.e.

 private void setupIOC()
        {
...
            FreshIOC.Container.Register<IDeviceDisplay, DeviceDisplayImplementation>();
        }

Then I resolve it later in app.cs class but exception occuring here:

            IDeviceDisplay deviceDisplay = FreshIOC.Container.Resolve<IDeviceDisplay>();

            // Get Metrics
            DisplayInfo mainDisplayInfo = deviceDisplay.MainDisplayInfo;

Anyway to resolve this so it returns DisplayInfo?

Im guessing its better to avoid the call to MainDisplayInfo with a condition check i.e if not supported like following:

if (DeviceInfo.Platform != DevicePlatform.Unknown)
            {
                   Safe to call deviceDisplay.MainDisplayInfo;
             }

Howdy - yes, the error is saying that the display API has no implementation in the reference (shared/cross-platform) assembly, because the implementations are provided for each specific platform (iOS/Android, etc.). In a 'headless' scenario like you are describing, you have no platform implementation so you end up with this.

Im guessing its better to avoid the call to MainDisplayInfo with a condition check i.e if not supported like following:

That should work; another test-friendly approach would be to register a mock implementation instead, like:

public class UnitTestDeviceDisplay : IDeviceDisplay
{
	public bool KeepScreenOn { get; set; }

	public DisplayInfo MainDisplayInfo => new DisplayInfo();
		
	public event EventHandler<DisplayInfoChangedEventArgs> MainDisplayInfoChanged;
}

Or you could use a mocking library, particularly if you need values on MainDisplayInfo to be sensible (in the above width/height etc. will be zero).

Avoiding the call works for now, the only reason MainInfo needs to be called is because I used a different ResourceDictionary with styles dependant on that device size. However in a unit test scenario this is fairly trivial. If I do need values Ill mock it with NSubstitute with I use for mocking. Appreciate the help. Thanks