Xamarin Forms Cross Platform Libraries and Dependency Services

This post is about how to set up cross platform libraries for Xamarin Forms, and how to implement Dependency Services in those libraries. The source code for these examples are here.

The example app is a very simple page, which shows a time string that is taken from a cross platform library, and a culture that is taken from a platform specific library via a dependency service. It looks like this…

Screen Shot 2018-02-10 at 14.02.43

Cross Platform Libraries

Adding a cross platform library is easy – simply add a Xamarin.Forms class library project to your solution, and add a project reference to your cross platform application project. You can then use classes from the library as you would expect.

Platform Libraries & Dependency Services

Things get interesting when you want to add dependency services to the library. For this you need to add an iOS class library project, and an Android class library project to your solution. You also need to add the Xamarin.Forms to both projects.

Next you have to set up the references. These are the references to add…

Sample App References: Cross Platform Library
iOS App References: Cross Platform Library, iOS Library
Android App References: Cross Platform Library, Android Library
Cross Platform Library References: -
iOS Library References: Cross Platform Library, Xamarin Forms
Android Library References: Platform Library, Xamarin Forms

Now you can define the dependency service interface in the cross platform library…

using System;

namespace SampleLibrary
{
    public interface ICultureProvider
    {
        string GetCultureString();
    }
}

And implement the interface in the platform specific libraries, here’s the iOS implementation…

using System;
using SampleLibrary.iOS;
using Xamarin.Forms;
using System.Threading;

[assembly: Dependency(typeof(CultureProvider))]
namespace SampleLibrary.iOS
{
    public class CultureProvider : ICultureProvider
    {
        public CultureProvider()
        {
        }

        public string GetCultureString()
        {
            return Thread.CurrentThread.CurrentCulture.ToString();
        }
    }
}

Remember to add the Dependency attribute! This needs to reference the implementation class, not the interface.

Now you can use DependencyService.Get to get access the service…

var cultureProvider = DependencyService.Get();
var culture = cultureProvider.GetCultureString();

For a regular dependency service defined in the application projects this would be enough. However using libraries introduces an extra foible. At compile time the application specific library might not be included in the project because there’s no reference to it in code. If this DependencyService.Get returns null. To fix this you need to add some code to the platform specific application to reference the platform specific library. This can be as simple as creating an instance of one of the classes in the library…

[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        global::Xamarin.Forms.Forms.Init();
        var foo = new SampleLibrary.iOS.CultureProvider();

        LoadApplication(new App());

        return base.FinishedLaunching(app, options);
    }
}

With the reference in place the dependency service will resolve correctly. This feels like a hack, but I haven’t found a better solution, if you have any ideas leave a comment!

Any better ideas??

Advertisements
Xamarin Forms Cross Platform Libraries and Dependency Services

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s