DependencyService in Xamarin
DependencyService is a static class in the Xamarin.Forms namespace. Shared or Portable projects can access the platform-based tweaks that are done in any specific platform projects using DependencyService.
How it works?
The key point is by defining an interface.
- Declare an interface in the Shared / Portable project.
- Implement the interface in the platform-specific projects.
- Register the class under the DependencyService Assembly with the Dependency attribute.
- Call the DependencyService.get method with the Interface. It will identify the platform and execute the implementation.
The following are a few catches here,
- The class that implements the Interface must have a parameterless constructor defined.
- The [assembly:] attribute must be declared above the namespace. I have often seen developers making this mistake.
- The implementation must be done in each platform-specific project in the Solution. It has a valid reason as well. Since we are implementing it in a shared repository, it is obvious that we will use the same code base for all of the platforms. In that case, the platform doesn't have the implementation so we will using aNullReferenceException.
Let's do it
Let's create a Xamarin.Forms Portable project with iOS, Android and Windows Phone. Name it DependencyDemo. Once the Solution is ready, add a new interface to the Portable project and name it asIDependencyDemo, add the following code to the interface.
- namespace DependencyDemo
- {
- public interface IDependencyDemo
- {
- string GetThePlatformMessage();
- }
- }
Build the Solution
Now let's implement the class in the platform-specific projects. Let's add new classes with the same name “DependencyImplementation” to each platform project and implement the interface in them.
Note: It is not required at all, for the class names to be the same. We have done it for our convention.
Android implementation
- [assembly: Xamarin.Forms.Dependency(typeof(DependencyDemo.Droid.DependencyImplementation))]
- namespace DependencyDemo.Droid
- {
- public class DependencyImplementation:IDependencyDemo
- {
- public string GetThePlatformMessage()
- {
- return "I am Android";
- }
- }
- }
iOS implementation
- [assembly: Xamarin.Forms.Dependency(typeof(DependencyDemo.iOS.DependencyImplementation))]
- namespace DependencyDemo.iOS
- {
- public class DependencyImplementation:IDependencyDemo
- {
- public string GetThePlatformMessage()
- {
- return "I am iOS";
- }
- }
- }
Windows Phone implementation
- [assembly: Xamarin.Forms.Dependency(typeof(DependencyDemo.WinPhone.DependencyImplementation))]
- namespace DependencyDemo.WinPhone
- {
- public class DependencyImplementation:IDependencyDemo
- {
- public string GetThePlatformMessage()
- {
- return "I am Android";
- }
- }
- }
Now let's test it by navigating back to the DemoDependency Portable project. Open the App.cs and place the following code in it.
- namespace DependencyDemo
- {
- public class App
- {
- public static Page GetMainPage()
- {
- string whoAmI = DependencyService.Get<IDependencyDemo>().GetThePlatformMessage();
- return new ContentPage
- {
- Content = new Label
- {
- Text = whoAmI,
- VerticalOptions = LayoutOptions.CenterAndExpand,
- HorizontalOptions = LayoutOptions.CenterAndExpand,
- },
- };
- }
- }
- }
Set the individual platform project as the Start Up Project and try to run the apps one after the other.
I hope this helps. Enjoy coding.