Xamarin is widely used to develop applications for mobile devices. It uses C# as its programming language, and wraps much of the functionality that is common between different mobile platforms behind a common interface. In cases where common functionality is not already wrapped in a common interface, the DependencyService class can be used to make one. Xamarin projects are divided into platform-specific sections, and a common section. To use DependencyService, the common section defines an interface that is implemented by classes in the platform-specific sections. The platform-specific classes are registered as services. When the common code needs to use the service, DependencyService will create an instance of the correct class for whichever platform is running and return its interface.
The first step in using DependencyService is to define the common interface. This is a standard C# interface class. It should be defined in the common section of the Xamarin project. The next step is to create the platform-specific classes that implement the interface. These should be in the platform-specific sections. Each class must be registered with DependencyService, which is usually done with an attribute. After the interface and classes are in place, the next step is to create an instance of one of the platform-specific classes at run-time. This is done through the DependencyService ‘Get’ function. The class that is created is the one for the platform that is running. The ‘Get’ function returns the class’s interface and the interface functions can be called.
The following example demonstrates using DependencyService in Xamarin:
File 1 – buffet/FoodMaker.cs
namespace buffet { /* Interface for the platform-dependent service */ public interface IFoodMaker { /* Declare the functions the service will implement */ int MakePancake(bool withBlueberries); int MakeOmelette(bool withMushrooms); } } |
File 2 – buffet.iOS/FoodMaker_iOS.cs
/* Register the iOS implementation of the IFoodMaker interface */ [assembly: Dependency(typeof(FoodMaker_iOS))] namespace buffet { public class FoodMaker_iOS : IFoodMaker { int MakePancake(bool withBlueberries) { // TODO – convince an iPhone to make a pancake }
int MakeOmelette(bool withMushrooms) { // TODO – convince an iPhone to make an omelette } } } |
File 3 – buffet.Android/FoodMaker_Android.cs
/* Register the Android implementation of the IFoodMaker interface */ [assembly: Dependency(typeof(FoodMaker_Android))] namespace buffet { public class FoodMaker_Android : IFoodMaker { int MakePancake(bool withBlueberries) { // TODO – convince an Android phone to make a pancake }
int MakeOmelette(bool withMushrooms) { // TODO – convince an Android phone to make an omelette } } } |
File 4 – buffet/MainPage.xaml.cs
namespace buffet { public class MainPage : ContentPage { private IFoodMaker food_maker;
/* Constructor for the main page that runs at startup */ public MainPage() { /* Create the platform-dependent class and save the interface for later */ food_maker = DependencyService.Get<IFoodMaker>(); }
/* Called when the user presses the make pancake button */ public OnPleaseMakePancakeClicked(object sender, EventArgs e) { /* Everyone ALWAYS wants blueberries */ food_maker.MakePancake(true); }
/* Called when the user presses the make omelette button */ public OnPleaseMakeOmelette(object sender, EventArgs e) { /* Nobody ever wants mushrooms */ food_maker.MakeOmelette(false); } } } |