After upgrading our Xamarin application to ArcGIS Runtime 100.12, we noticed that the ESRI.ArcGISRuntime.Xamarin.Forms assembly is now a "reference assembly". So it can no longer be used to instantiate objects. We have a lot of .NET Core unit tests that use objects from it (like MapView as an example). .NET Core was used because of performance improvement over UWP.
If a MapView is only created and used in a test, then the ESRI.ArcGISRuntime.WPF assembly can be used. But for our shared libraries where MapView is used as a member/parameter it will not work anymore (type mismatch).
Does someone has a solution for this situation?
What was the reason to define the ESRI.ArcGISRuntime.Xamarin.Forms assembly as reference-assembly?
Why does ESRI not provide interfaces for the ESRI.ArcGISRuntime.Xamarin.Forms objects (GeoView, MapView, SceneView) in the .NET Standard ESRI.ArcGISRuntime? That would be really helpful to be able to use that objects in tests independent of the platform. Sure, we can define our own interface and proxy-classes to achieve that, but should that not be a part of the SDK?
Xamarin.Forms only supports the iOS, Android and UWP at runtime - it cannot be used with .NET Standard and has never been supported. The .NET Core target relies on WPF, and we have no Forms binding for WPF.
If you need to run on .NET Core, you'll need to not reference the Forms package.
> Why does ESRI not provide interfaces for the ESRI.ArcGISRuntime.Xamarin.Forms objects
We don't provide interfaces for types that frequently evolve, as changing that interface would be a breaking change.
Thanks for taking the time to reply and provide that information. Unfortunately though this puts us in a really difficult position. That effectively leaves us with only one possible solution which is to use a UWP unit test app to run our tests. This is a problem because the UWP unit test app is really bad in the following ways (not your fault):
So for those reasons, we'd really prefer not to run our tests in UWP, and would rather do .Net Core. You see that the Xamarin Forms team uses .Net framework, which has similar performance and coverage capabilities to .net core tests, to run a good chunk of their tests:
Additionally the fact that the Runtime is available as a .Net standard library would seem to imply that it should run in anything that supports .Net standard. That's kind of the main point of .Net standard. As well, this worked before, so why should it not work now? Even if it wasn't officially supported, it was very beneficial to us.
As for interfaces, yeah sure, it's technically a breaking change if someone implements IMapView and you change it, but I feel like it could be remedied by just putting a comment on the interface indicating that it will change over time, and you should expect your code to not compile if you upgrade and you have implemented said interface. I think people could easily live with that if it buys them the ability to more easily unit test their app. I understand not wanting to create breaking changes, but it's coming at the cost of testability.
At the end of the day, I really don't see how it will be possible for us to efficientiently write and run unit tests with the restrictions that have been imposed. Do you have any suggestions? What do you do internally?
At this point, we're going to have to make some hard decisions.
What I'd suggest you do is split your unit tests into two: The ones you run on .NET Core only references the 'Esri.ArcGISRuntime' nuget package, as this one is supported on .NET Core. These should be all your non-UI tests. The Forms package contains Forms specific types that are meant to be used in UI so you can use this in UI Tests which must be run on a device that we support forms on. Using the Forms libraries in a .NET Core application in U11 wasn't supported, isn't tested, and you could easily get you into runtime exceptions.
> As for interfaces, yeah sure, it's technically a breaking change if someone implements IMapView and you change it, but I feel like it could be remedied by just putting a comment on the interface indicating that it will change over time
Unfortunately it still breaks binary compatibility. If say you use a 3rd party library or plug-in that hasn't been compiled for v.next yet, you'd be stuck on the old version until all your dependencies have been updated.
For .NET Maui, since we're only compiling that for .NET 6, we're going to solve that problem with default interface members, so it will be non-breaking there, and yes you'll get an IMapView interface with Maui (and we'll probably also tell you not to extend it).
> Additionally the fact that the Runtime is available as a .Net standard library would seem to imply that it should run in anything that supports .Net standard. That's kind of the main point of .Net standard
That's not quite the case. .NET Standard ensures you have a common set of APIs to code against across many platforms. But it isn't a runtime, and there is no such thing as a ".NET Standard Application" (hence why you can only make .NET Standard class libraries). At the end of the day you still have to compile your application for a specific runtime. It's true that many .NET class libraries only relies on the runtime APIs provided by .NET, so they are usable on all the platforms .NET Core runs, but ArcGIS Runtime relies not only this, but also its own native runtime that is specifically compiled for each platform. Those runtime platforms today are win32, uwp, ios and android.
In the next release we'll actually have our assemblies much more clearly attributed with platform support attributes, so you'd get proper warnings if you try and run this on a platform that isn't indicated as supported. .NET Core 3,1 itself actually supports running on many platforms, but again requires the correct runtime for that to work, and we've been quite clear that it was only Windows that was supported there. With .NET 5, it's a little more clear as the target is "net5.0-windows" and not just the base "net5.0" target, but that wasn't something we could do in 3.1, although it got implied by the WPF dependency it had (for U13 we hope to provide net6.0-windows, net6.0-ios and net6.0-android targets - we'll still provide a net6.0 reference assembly for compiling your cross platform business logic, but in the end, you'll still need to target a specific platform to run them).
So bottom line: The netstandard target is really only supported for class libraries. For running applications, you much pick a supported platform, and .NET Core isn't supported with Forms.