Skip to content

Dependency Injection

DependencyService allows apps to call into platform-specific functionality from shared code. This functionality enables Xamarin.Forms apps to do anything that a native app can do.

DependencyService is a dependency resolver. In practice, an interface is defined and DependencyService finds the correct implementation of that interface from the various platform projects.

Setting Up DependencyService

Xamarin.Forms apps need four components to use DependencyService :

  • Interface – The required functionality is defined by an interface in shared code.
  • Implementation Per Platform – Classes that implement the interface must be added to each platform project.
  • Registration – Each implementing class must be registered with DependencyService via a metadata attribute. Registration enables DependencyService to find the implementing class and supply it in place of the interface at run time.
  • Call to DependencyService – Shared code needs to explicitly call DependencyService to ask for implementations of the interface.

Danger

Note that implementations must be provided for each platform project in your solution. Platform projects without implementations will fail at runtime.

Interface Definition

The interface is defined in the Xamarin Forms project. We are going to define an interface to get the path for the SQLite database. Each platform will need to provide the concrete implementation.

IFileHelper.cs

public interface IFileHelper
{
    string GetLocalPath(string filename);
}

Implementation

On each platform we need to provide the implementation for the interface definition.

Android Implementation

This code goes in the Android project.

FileHelper.cs

public class FileHelper : IFileHelper
{
    public string GetLocalPath(string filename)
    {
        var documentsFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
        return Path.Combine(documentsFolder, filename);
    }
}

iOS Implementation

This code goes in the iOS project.

FileHelper.cs

public class FileHelper : IFileHelper
{
    public string GetLocalPath(string filename)
    {
        //Get path of the document folder
        var documentFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
        //Get path of the Library folder
        var libraryFolder = Path.Combine(documentFolder, "..", "Library", "Databases");
        if (!Directory.Exists(libraryFolder))
        {
            Directory.CreateDirectory(libraryFolder);
        }
        return Path.Combine(libraryFolder, filename);
    }
}

Registration

Each implementation of the interface needs to be registered with DependencyService with a metadata attribute. The following code registers the implementation for iOS :

[assembly: Dependency(typeof(FileHelper))]
namespace DataBindingDemo.iOS
{
    public class FileHelper : IFileHelper { ... }
}

and for Android :

[assembly: Dependency(typeof(FileHelper))]
namespace DataBindingDemo.Droid
{
    public class FileHelper : IFileHelper { ... }
}

Call to DependencyService

Once the project has been set up with a common interface and implementations for each platform, use DependencyService to get the right implementation at runtime :

// Resolve the FileHelper
var fileHelper = DependencyService.Get<IFileHelper>();

Note

Using DependencyService.Get<IFileHelper>() we can resolve the platform specific code for the FileHelper. On iOS it will call the iOS specific FileHelper code and on Android, it will resolve to the Android specific Filehelper code we defined.