Dependency Injection for iOS and Android Using Xamarin

Dependency injection is one of my key design patterns that I commonly implement in any architecture. Dependency injection is one of the loosest couplings one can achieve in a design pattern, since the construction and specification of any relationships are managed by the dependency injection container. The common way to supply a relationship is through a property or a constructor. For instance, an iOS controller may look like the following:


public class TestController : UIViewController
{
private IService1 _s1;
private IService2 _s2;

public TestController(IService1 s1, IService2, s2) : base(..) {
_s1 = s1;
_s2 = s2;
}
}

Where IService1 and IService2 are interfaces defined in the dependency injection container. The DI container creates the TestController class instance, and populates the services. Since the typical way to create a controller is to add it to the navigation controller, constructor injection is a great technique for iOS:


var container = DIContainer.Instance;
//At this point, new controller created and services defined
var newController = container.GetInstance();

//this refers to the current UIViewController;
//code below adds the controller to the stack
this.NavigationController.PushViewController(newController, true);

However, constructor injection does not work in Android’s architecture. This is because Android doesn’t expose the activity creation process to the developer. Android does expose the initialization of a controller though, which makes it a more ideal candidate for property injection. Each android activity has a specific lifecycle that it follows, the create method is usually a good place to put code like this. However, because services are often utilized within the create method of the activity, we need something that’s a step sooner than that. I ended up resorting to doing this during the constructor, as in the sample activity below:


public abstract class BaseActivity : Activity
{

protected void CheckForDependencies()
{
var props = this.GetType ().GetProperties ();
foreach (var prop in props) {
if (prop.GetCustomAttributes(typeof(ServiceDependencyAttribute), false).Length > 0) {
//Inject dependency
try
{

object instance = App.Current.Resolver.GetInstance (prop.PropertyType);
if (instance != null)
prop.SetValue (this, instance, null);

}
catch(Exception ex) {
Toast.MakeText (this, "An error occurred: " + ex.Message, ToastLength.Long);
}
}
}
}

public BaseActivity()
{
this.CheckForDependencies ();
}

}

And a sample activity like:


public class AchievementsActivity : BaseActivity
{

[ServiceDependency]
public IErrorHandlerService ErrorHandler { get; set; }

[ServiceDependency]
public IAchievementsLoader Achievements { get; set; }

[ServiceDependency]
public IMessageDialogService Messages { get; set; }

}

The common problem with using inheritance is that you have to implement a custom base class for every different type of activity: list activities, fragments, and every other activity type. Otherwise, you’d have to duplicate the property injection logic. However, inheritance is the best way to address the problem and essentially “wrap” the base functionality.

Advertisements

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s