Skip to content

rdavisau/essential-interfaces

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

essential-interfaces-generator

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).

Why would I want this?

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!

How does it work?

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.

How do I use the interfaces?

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.

Does it play nice with the Mono Linker?

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.

Is reading from the source directly a bit brittle?

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.

I just want to get the raw output!

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.

About

Interfaces for Xamarin.Essentials

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages