Xamarin.Forms DependencyService: Platform API Access Guide
Learn how to use Xamarin.Forms DependencyService to call platform‑specific APIs from shared code, including registration, resolution, diagnostics, and limitations.
08 Sept 2026, 14:37 UTC

Desired Outcome
You need to call platform‑specific APIs—such as battery level, device model, or native file system access—from shared Xamarin.Forms code without coupling your business logic to Android or iOS. The DependencyService resolves this by letting you define an interface in the shared project and register platform‑specific implementations that are discovered at runtime.
Prerequisites
- A Xamarin.Forms solution with a shared .NET Standard project and separate iOS and Android head projects.
- Platform projects that reference the shared project.
- Familiarity with C# interfaces and assembly attributes.
Define the Shared Contract
Create a public interface in the .NET Standard project. This interface is the only type your shared code should reference; the concrete implementations remain invisible to portable code.
namespace MyApp.Services
{
public interface IDeviceInfo
{
string GetDeviceModel();
}
}
Implement and Register Platform Code
Each platform project provides its own implementation. Registration uses an assembly‑level attribute placed outside any namespace or class declaration so the Xamarin.Forms build targets can discover it during startup.
Android Implementation
In the Android project, add a class that implements the interface and decorate the assembly. The attribute must appear before any namespace declarations in the file, typically in AssemblyInfo.cs or directly above the implementation class at the file scope.
using Android.OS;
using MyApp.Services;
using Xamarin.Forms;
[assembly: Dependency(typeof(MyApp.Droid.DeviceInfo))]
namespace MyApp.Droid
{
public class DeviceInfo : IDeviceInfo
{
public string GetDeviceModel()
{
return Build.Model;
}
}
}
iOS Implementation
The iOS project follows the same pattern. Place the registration attribute at assembly scope and implement the interface using iOS APIs.
using MyApp.Services;
using UIKit;
using Xamarin.Forms;
[assembly: Dependency(typeof(MyApp.iOS.DeviceInfo))]
namespace MyApp.iOS
{
public class DeviceInfo : IDeviceInfo
{
public string GetDeviceModel()
{
return UIDevice.CurrentDevice.Model;
}
}
}
Resolve the Service in Shared Code
Call DependencyService.Get<T>() from shared code—such as a ViewModel, page, or service—to obtain the registered implementation. The method returns the platform instance or null if no implementation was found.
using MyApp.Services;
using Xamarin.Forms;
public class DeviceViewModel
{
public string Model { get; private set; }
public DeviceViewModel()
{
var deviceInfo = DependencyService.Get<IDeviceInfo>();
Model = deviceInfo?.GetDeviceModel() ?? "Unknown";
}
}
Use the null‑conditional operator (?.) and a fallback value so a missing registration does not crash the shared project on an unconfigured platform.
Expected Checks and Diagnostics
- Attribute placement: The
[assembly: Dependency]attribute must be outside the namespace and class. If it is nested inside a class, the registrar will not find it. - Interface visibility: The shared interface must be
public. Internal interfaces are not visible across assembly boundaries. - Platform result: Run the app on an Android emulator and an iOS simulator. The
Modelproperty should reflect the native device string, not the shared fallback value. - Missing implementation path: Temporarily comment out one platform registration and confirm the shared code returns the fallback string rather than throwing a
NullReferenceException.
Recovery Options
If DependencyService.Get<IDeviceInfo>() returns null, the most common causes are a misplaced registration attribute or a missing using Xamarin.Forms; directive in the platform file. Check that the attribute is at file scope and that the implementation class is public. If unit tests fail because the service locator cannot resolve interfaces outside a mobile runtime, wrap the interface behind an injectable abstraction in your tests rather than relying on DependencyService directly.
Limitations and Modern Alternatives
DependencyService is a service locator, not a full dependency injection container. It resolves types at runtime, which makes compile‑time validation impossible and complicates unit testing without extensive mocking. Xamarin.Forms is also transitioning toward .NET MAUI, where the recommended pattern is constructor injection through IServiceProvider and the host builder. For new Xamarin.Forms work, treat DependencyService as a pragmatic bridge for simple platform abstractions, but prefer explicit DI for complex graphs.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.