When using a container for dependency injection in your Xamarin.Forms app, you may find yourself trying to use a plugin or library that is static that you want to register with your container. Having static s in our code makes it hard to test and causes coupling. In this post, I will demonstrate using Prism.Forms how to inject a static plugin or library that may or may not expose an abstraction.

In Xamarin cross-platform world, plugins and libraries are abundantly available and used, which is a good thing since we do not need to reinvent the wheel in most cases i.e. Settings, Location, Permission, etc., can be handled by using a reliable plugin (like those from Xamarin) or other well supported libraries. Some provide an abstraction (interface) to be used to get the implementations, others do not. So, let’s see how we can inject both of these types of libraries or plugins.

Note: For simplicity, I am going to lump ‘Plugin’ and ‘Library’ into ‘library’, and ‘Abstraction’ and ‘Interface’ into ‘interface’.

The MVVM-Friendly Statics

Some libraries such as Xamarin’s Setting Plugin and Connectivity plugin expose interface such as ISettings and IConnectivity that we can register with our container for injection. In Prism.Forms, we can simply register and instance of these libraries with our container,

protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterInstance<ISettings>(CrossSettings.Current); containerRegistry.RegisterInstance<IConnectivity>(CrossConnectivity.Current); }

and that’s it. To inject,

public MyViewModelOrService(ISettings settings, IConnectivity connectivity) {}

The Not-So-MVVM-Friendly Statics

Now, what about dealing with a static library that does not expose an interface, not to worry, design patterns to the rescue. We can simply wrap the static class using Adapter Pattern. Let’s say you have a static library for logging called StubbornLogger . Consider the following implementation,

public static class StubbornLogger { public static void Log(string message) { // Log message } }

If your ViewModel is using this, then while unit testing, you would have to somehow get to the Log() , which is challenging.

To make it readily injectable and testable, we can wrap this class,

public interface ILoggerWrapper { void Log(string message) } public class LoggerWrapper : ILoggerWrapper { public void Log(string message) { StubbornLogger.Log(message); } }

Now, simply register ILoggerWrapper with your container,

containerRegistry.Register<ILoggerWrapper>();

and inject away,

public MyViewModelOrService(ISettings settings, IConnectivity connectivity, ILoggerWrapper loggerWrapper) {}

By abstracting away your static library, you decoupled your code and made it future-proof. You can swap out the implementation anytime without impacting your code as long as you conform to ILoggerWrapper .

Have questions, comments? Leave them below. Enjoy!

Icon made by Kiranshastry from www.flaticon.com