Registration & Resolution of DependencyService in Xamarin.FormsIn Xamarin.Forms namespace, the DependencyService is a static class.
Shared and transportable projects can use the platform-based modifications performed in certain platform projects using DependencyService. Whenever we use DependencyService of Xamarin. Forms to invoke the original functions of the platform, the platform implementations must be enrolled with the DependencyService, and then to invoke them it must be resolved from the shared code.
Registering Platform Implementations
If the Xamarin.Forms can able to locate the platform implementations at the runtime, the platform implementations must be registered with the DependencyService. Registration can be done using two ways, the first is, by DependencyAttribute
, and the second is, with Register
and RegisterSingleton
methods.
1. Registering using DependencyAttribute
:
Here, the attribute is used for registering a platform implementation with DependencyService. It also indicates that the mentioned type gives a solid implementation of the interface.
using SimplePrg.Services1; using SimplePrg.UWP.Services; using Windows.UI.ViewManagement; using Xamarin.Forms; [assembly: Dependency(typeof(DeviceOrientationService))] namespace SimplePrg.UWP.Services { class DeviceOrientationService : IDeviceOrientationService { public DeviceOrientation GetOrientation() { ApplicationViewOrientation orientation = ApplicationView.GetForCurrentView().Orientation; return orientation == ApplicationViewOrientation.Landscape ? DeviceOrientation.Landscape : DeviceOrientation.Portrait; } } }
Here, in the above code of UWP, DependencyService is registered with the DeviceOrientationService using the DependencyAttribute.
Same as this, the interface IDeviceOrientationService’s implementations must also be registered with the DependencyAttribute on the other platforms.
2. Registering using methods:
To register a platform implementation with the DependencyService, we use any of the two methods i.e. DependencyService.Register method or DependencyService.RegisterSingleton method.
Using Register method:
using SimplePrg.Services1; using SimplePrg.UWP.Services; using Xamarin.Forms; namespace SimplePrg.UWP { public sealed partial class MainPage { public MainPage() { this.InitializeComponent(); LoadApplication(new SimplePrg.App()); DependencyService.Register< IPhotoPickerService, TextToSpeechService>(); DependencyService.Register<IDeviceOrientationService, DeviceOrientationService>(); DependencyService.Register<IPhotoPickerService, PhotoPickerService>(); } } }
In this code, the Register method is registering the non-changeable type, DeviceOrientationService, PhotoPickerService, TextToSpeechService in the opposite of IDeviceOrientationService, IPhotoPickerService, and IPhotoPickerService interfaces respectively.
On the other end, the Register method’s overloading can be used for registering the DependencyService with any platform implementation.
- Using RegisterSingleton method:
- For using the RegisterSingleton method, we will have to a very small change in the above code.
DependencyService.Register<IDeviceOrientationService, DeviceOrientationService>();
The above code will be replaced with:
var service = new DeviceOrientationService(); DependencyService.RegisterSingleton<IDeviceOrientationService>(service);
Therefore, as a singleton, the DeviceOrientationService object instance will be registered with the IDeviceOrientationService interface using the DependencyService.RegisterSingleton method.
Resolving Platform Implementations
Before the platform implementations are invoked they must be resolved and usually it is done in the shared code by using the DependencyService.Get<T> method.
Otherwise, we can also use DependencyService.Resolve<T> method instead of DependencyService.Get<T> method.
By default, the platform implementations having the parameterless constructors will only be resolved by the DependencyService.
Howsoever, a method of dependency resolution can be able to inject into the Xamarin.Forms that are using dependency injection factory methods or container methods for resolving the platform implementations.
This method can be used to resolve the platform implementations having parameterized constructors.
Using Get<T> method:
The platform implementations of the interface T are retrieved by the Get<T> method at the runtime.
On the other hand, either an instance of the method is created as a singleton or the returning of the instance as a singleton is observed that was been registered with the RegisterSingleton method using DependencyService.
In both cases, the life of the instance will be generated for a lifetime till the application will be in a used state.
Also any subsequent for resolving the same platform implementation will be retrieving the same instance.
The only difference between Get<T> and Resolve<T> method is its name only, everything else is the same in both methods.
MainPage.xaml.cs
using System; using System.IO; using Xamarin.Forms; using SimplePrg.Services1; namespace SimplePrg { public partial class MainPage : TabbedPage { public MainPage() { InitializeComponent(); } public void OnGetDeviceOrientationButtonClicked(object sender, EventArgs e) { DeviceOrientation orientation = DependencyService.Get<IDeviceOrientationService>().GetOrientation(); orientationLabel.Text = orientation.ToString(); } async void OnPickPhotoButtonClicked(object sender, EventArgs e) { (sender as Button).IsEnabled = false; Stream stream = await DependencyService.Get<IPhotoPickerService>().GetImageStreamAsync(); if (stream != null) { image.Source = ImageSource.FromStream(() => stream); } (sender as Button).IsEnabled = true; } async void OnSpeakButtonClicked(object sender, EventArgs e) { ITextToSpeechService service = DependencyService.Get<ITextToSpeechService>(DependencyFetchTarget. NewInstance); using (service as IDisposable) { await service.SpeakAsync("Hello All!"); } } } }
cs file of Shared Project
Managing the Resolved Objects for Lifetime:
To resolve platform implementations as singletons is the default behavior of DependencyService class.
And so, the platform implementations of any application survive for a lifetime.
This behavior of platform implementations is specified with DependencyFetchTarget which is an optional argument on Get<T> and Resolve<T> methods.
Platform implementations are always resolved as singletons as the Get<T> and Resolve <T> both the methods set their optional arguments to DependencyFetchTarget.GlobalInstance.
If we want to change this behavior, we can specify DependencyFetchTarget.NewInstance as an argument to the Get<T> and Resolve<T> methods and so the new instance of platform implementations is created.
<?xml version="1.0" encoding="utf-8" ?> <TabbedPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SimplePrg.MainPage" BackgroundColor="DeepSkyBlue"> <ContentPage Title="Device Orientation" BackgroundColor="LightSeaGreen"> <StackLayout Margin="20,35,20,20"> <Label Text="Click Button to Get Device Orientation" HorizontalTextAlignment="Center" HorizontalOptions="Center" TextColor="Cornsilk" FontSize="45"/> <Button Text="Get Orientation of Device" FontSize="25" Clicked="OnGetDeviceOrientationButtonClicked" /> <Label x:Name="orientationLabel" HorizontalOptions="Center" /> </StackLayout> </ContentPage> <ContentPage Title="Photo Selector" BackgroundColor="LightSlateGray"> <StackLayout Margin="20,35,20,20"> <Label Text="Click Button to Select Image" HorizontalTextAlignment="Center" HorizontalOptions="Center" TextColor="Cornsilk" FontSize="45"/> <Button Text="Pick Photo" FontSize="25" Clicked="OnPickPhotoButtonClicked" /> <Image x:Name="image" /> </StackLayout> </ContentPage> <ContentPage Title="Text to Speech" BackgroundColor="DarkSeaGreen"> <StackLayout Margin="20,35,20,20"> <Label Text="Click Button to Listen" HorizontalTextAlignment="Center" HorizontalOptions="Center" TextColor="Cornsilk" FontSize="45"/> <Button Text="Say Hello World" FontSize="25" Clicked="OnSpeakButtonClicked" /> </StackLayout> </ContentPage> </TabbedPage>
- In the above code, we have created a TabbedPage, and in that, there are three ContentPages present.
- In all the ContentPage there is a button present that performs different tasks after it is clicked.
- In the first ContentPage, we fetch the Orientation of the device, in the second page we open the OpenDialogBox from which the user selects any random picture and that will be displayed on the screen, and in the last ContentPage, we have written code that speaks the content that is passed to it using the DependencyService at the time of click event of the button.
- Output:
Conclusion
By Registering and Resolving the DependencyService in Xamarin.Forms, it becomes easy for the developer and also the application to invoke the local functionality of each platform and to process that in every particular platform.
Author Bio: Vinod Satapara – Technical Director, iFour Technolab Pvt. Ltd.
Technocrat and entrepreneur with years of experience building large-scale enterprise web, cloud and mobile applications using latest technologies like ASP.NET, CORE, .NET MVC, Angular and Blockchain. Keen interest in addressing business problems using latest technologies and help organization to achieve goals.
Hire Asp.net developers from iFour Technolab to get your requirements done.
Image: