Generates interfaces for the Xamarin.Essentials library.
📝️ For .NET MAUI Users: the base MAUI library includes the originally-separate Essentials APIs, and they come with interfaces out of the box - hurrah! So you don't need to use this any more. If you install a recent version of Xamarin.Essentials.Interfaces into a MAUI app, you'll get 'compatibility interfaces'. These match the 'shape' of Xamarin.Essentials interfaces, but also implement and delegate to the MAUI interfaces and implementations, which have been moved into various different namespaces. This gives you the option of deferring the namespace changes, or (with the help of a few global usings) keeping your code compatible with both XF and MAUI for the time being.
If you're after the interfaces themselves, you can install them from NuGet:
Install-Package Xamarin.Essentials.Interfaces
You can also grab the raw source outputs from here (see the end of this readme for a few more details).
The Xamarin.Essentials library is a great initiative by the Xamarin team to provide a simple, consolidated, endorsed and low-overhead set of cross-platform apis for mobile applications. As a core design decision, the Essentials library does not include any interfaces - for several reasons - and all features are accessed via static methods, properties and events. If you use dependency injection in your mobile apps, you may miss the interfaces that the 'old skool' plugins for Xamarin typically shipped with - fret not, essential-interfaces-generator is here!
essential-interface-generator reads the Xamarin.Essentials source and generates an intermediate model representing the apis exposed by Xamarin.Essentials (RoslynModelGenerator
). It then uses that model to generate C# code containing matching interface definitions for the apis, and implementations for interfaces that forward members on to the static classes provided by Xamarin Essentials (ImplementationGenerator
). These are dropped into an output project with some basic version information (ProjectMutator
) and packed for NuGet.
Install the NuGet package and get registering! Each Xamarin.Essentials api has a matching interface and implementation in the Xamarin.Essentials.Interfaces
and Xamarin.Essentials.Implementation
namespaces respectively. These follow a basic pattern:
Xamarin.Essentials API: Thing
Interface: IThing
Implementation: ThingImplementation
Knowing this, you can register each implementation you need with its matching interface. For example:
using Xamarin.Essentials.Implementation;
using Xamarin.Essentials.Interfaces;
builder.Register<IAccelerometer, AccelerometerImplementation>();
builder.Register<IBattery, BatteryImplementation>();
Alternatively, you can use the marker interface IEssentialsImplementation
(adopted by all implementation classes) and reflection to find and register all implementation classes at once. When using this approach, you may need to hint the linker to preserve the implementations (since they are never directly referenced). The technique typically used for this purpose is falseflagging.
For mocking, just work as you would with any other mocks:
var mockGeo = new Mock<IGeocoding>();
mockGeo.Setup(x => x.GetPlacemarksAsync(It.IsAny<double>(), It.IsAny<double>()))
.ReturnsAsync(Enumerable.Empty<Placemark>());
// etc.
Yes. The generated assembly is marked with the LinkerSafe
attribute, making it eligible for linking regardless of the link level of your consuming project. Only the types and members you invoke from your application are included in compiled outputs, even if you register them all. You can verify this using a dissassembler like dotPeek.
Probably. The generator makes assumptions based on the current conventions in the repo. Since it is being run against each commit in the Xamarin.Essentials repo, any breaking changes should become clear quickly enough.
No problems, you totally can! The interfaces and implementations being generated off each commit to Xamarin.Essentials are available here. That's a mono/WASM page so give it a few seconds to load.