IoC Containers with Xamarin
When writing cross platform apps with Xamarin, our goal is share as close to 100% of our code across all the platforms. While this is an admirable goal to aim for, it is not realistic. Very often, we find ourselves needing to access a platform specific feature from our shared code. We have multiple options in this case. We could use a Shared Project with compiler directives, class mirroring, or partial classes and access the platform code alongside our shared code. Alternatively we could use an abstraction for the functionality in our shared code, and pass an implementation of the abstraction into our shared code. In this way, our shared code only needs to know about the abstraction, typically an interface. This strategy, known as Inversion of Control or IoC, works especially well when using Portable Class Libraries (PCL) for our shared code.
Even when using IoC, manually managing all of our dependencies, including instantiating the dependency tree for an object, can be tedious at best. This is where we turn to a host of existing IoC containers. The .net ecosystem has long had a wealth of choices in IoC containers. Some of the more popular ones include StructureMap, Castle Windsor, Ninject, Unity, and Autofac. These are by no means the only choices, up to and including rolling our own.
Not all of these containers are able to run in limitations imposed by mobile devices though. Phones and tablets have constrained cpu and memory, and iOS devices forbid JIT compiling and certain uses of reflection. Additionally, the library authors have to specifically compile for Xamarin.iOS and Xamarin.Android, either individually or as part of a PCL.
I decided to put together some sample code showing how the Xamarin-compatible IoC containers work. As of this writing (July, 2014) I have limited the comparison only to IoC containers that 1) I could get to work successfully and 2) had an available Nuget package for easy installation. I did not want to go through the process of pulling individual repositories and building the source from scratch, although that is a valid option. This excluded some options that I do want to mention as alternatives.
- Xamarin.Forms Dependency Service. This is really more of a Service Locator than it is an IoC container. Also, it is only available as part of Xamarin.Forms.
- OpenNetCF. There is no nuget package for this library. Also, it requires custom attributes be added to the shared code, diminishing the usefulness.
- XPlatUtils. There is no nuget package for this library.
The libraries that I focused on were Autofac, MvvmCross, Ninject, TinyIoc, and Unity.
All of the code is available from my Github Repo
Sample Project
In the sample project, we have a single IoCDemo.Core project. This project contains the interface abstractions for our platform specific projects (ISettings and IPlatform) and a concrete ViewModel (MainViewModel) which takes the two interfaces as constructor dependencies. For each library, I created an iOS and an Android project to demonstrate wiring up the dependencies to platform specific implementations and creating the view model. Each container will be wired up in an App.cs file in each platform.
Some of the IoC containers have the ability to scan your assemblies and automatically wire up your dependecies. I chose not to use this ability. In a mobile app, every bit of cpu power is precious. I would rather spend the extra few seconds to write the code to wire up the dependency once at development time than have the app scan the assemblies every single time it is started.
Autofac
Install-Package Autofac
Wiring up the container
using Autofac;
using IoCDemo.Core;
namespace AutoFacDemo.iOS
{
public class App
{
public static IContainer Container { get; set; }
public static void Initialize()
{
var builder = new ContainerBuilder();
builder.RegisterInstance(new ApplePlatform()).As<IPlatform>();
builder.RegisterInstance(new AppleSettings()).As<ISettings>();
builder.RegisterType<MainViewModel> ();
App.Container = builder.Build ();
}
}
}
Resolving the view model
MainViewModel viewModel = null;
using (var scope = App.Container.BeginLifetimeScope ()) {
viewModel = App.Container.Resolve<MainViewModel> ();
}

MvvmCross
Install-Package MvvmCross.HotTuna.CrossCore
Wiring up the container
using Cirrious.CrossCore;
using IoCDemo.Core;
using Cirrious.CrossCore.IoC;
namespace MvvmCrossDemo.iOS
{
public static class App
{
public static void Initialize ()
{
MvxSimpleIoCContainer.Initialize ();
Mvx.RegisterType<IPlatform, ApplePlatform> ();
Mvx.RegisterType<ISettings, AppleSettings> ();
}
}
}
Resolving the view model
var viewModel = Mvx.IocConstruct<MainViewModel> ();

Ninject
Install-Package Portable.Ninject
Wiring up the container
using Ninject;
namespace NinjectDemo.iOS
{
public static class App
{
public static StandardKernel Container { get; set; }
public static void Initialize()
{
var kernel = new Ninject.StandardKernel(new NinjectDemoModule());
App.Container = kernel;
}
}
}
Resolving the view model
var viewModel = App.Container.Get<MainViewModel> ();

TinyIoc
Install-Package TinyIoc
Wiring up the container
using TinyIoC;
using IoCDemo.Core;
namespace TinyIoCDemo.iOS
{
public static class App
{
public static void Initialize ()
{
var container = TinyIoCContainer.Current;
container.Register<IPlatform, ApplePlatform> ();
container.Register<ISettings, AppleSettings> ();
}
}
}
Resolving the view model
var viewModel = TinyIoC.TinyIoCContainer.Current.Resolve<MainViewModel> ();

Unity
Install-Package Unity
Wiring up the container
using Microsoft.Practices.Unity;
using IoCDemo.Core;
namespace UnityDemo.iOS
{
public class App
{
public static UnityContainer Container { get; set; }
public static void Initialize()
{
App.Container = new UnityContainer();
App.Container.RegisterType<IPlatform, ApplePlatform> ();
App.Container.RegisterType<ISettings, AppleSettings> ();
}
}
}
Resolving the view model
var viewModel = App.Container.Resolve (typeof(MainViewModel), "mainViewModel") as MainViewModel;

Again, checkout the sample app on my Github repo to compare our IoC container choices for Xamarin.
From:http://arteksoftware.com/ioc-containers-with-xamarin/
IoC Containers with Xamarin的更多相关文章
- MVVMLight - IOC Containers and MVVM
在面向对象编程的早期,开发者要面对在应用程序或者类库中创建或检索类的实例的问题.针对这个问题有很多的解决方案.在过去几年中,依赖注入(DI)和控制反转(IoC)在开发者中很流行,并且取代了老的方案,比 ...
- [VueJS + Typescript] Decouple Dependencies Using IoC Containers in Vue with TypeScript and InversifyJS
Using Object Oriented Programming, OOP, style allows us to apply Inversion of Control, IoC, and more ...
- [LINK]List of .NET Dependency Injection Containers (IOC)
http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx I'm trying to expand my ...
- 译:Spring框架参考文档之IoC容器(未完成)
6. IoC容器 6.1 Spring IoC容器和bean介绍 这一章节介绍了Spring框架的控制反转(IoC)实现的原理.IoC也被称作依赖注入(DI).It is a process wher ...
- How to Make Portable Class Libraries Work for You
A Portable Class Library is a .NET library that can be used (in binary form, without recompiling) on ...
- MVC Controller Dependency Injection for Beginners【翻译】
在codeproject看到一篇文章,群里的一个朋友要帮忙我翻译一下顺便贴出来,这篇文章适合新手,也算是对MEF的一个简单用法的介绍. Introduction In a simple stateme ...
- Spring Framework------>version4.3.5.RELAESE----->Reference Documentation学习心得----->关于spring framework中的beans
Spring framework中的beans 1.概述 bean其实就是各个类实例化后的对象,即objects spring framework的IOC容器所管理的基本单元就是bean spring ...
- Asp.Net Web API 2第十一课——在Web API中使用Dependency Resolver
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文主要来介绍在Asp.N ...
- How To Easily Call WCF Services Properly z
Please note: this article has been superceded by the documentation for the ChannelAdam WCF Library. ...
随机推荐
- js数组基本操作
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtm ...
- 基于CommonsChunkPlugin,webpack打包优化
前段时间一直在基于webpack进行前端资源包的瘦身.在项目中基于路由进行代码分离,http://www.cnblogs.com/legu/p/7251562.html.但是打包的文件还是很大,特别是 ...
- day7 socket网络编程
Python Socket网络编程 Socket是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于Socket来完成通信的 ...
- 【LOJ】#2059. 「TJOI / HEOI2016」字符串
题解 我们冷静一下,先画一棵后缀树 然后发现我们要给c和d这一段区间在[a,b]这一段开头的串里找lcp 而lcp呢,就是c点的祖先的到根的一段,假如这个祖先的子树里有[a,b - dis[u] + ...
- USACO 6.4 Electric Fences
Electric FencesKolstad & Schrijvers Farmer John has decided to construct electric fences. He has ...
- Pig的安装和简单使用
1.Pig是基于hadoop的一个数据处理的框架. MapReduce是使用java进行开发的,Pig有一套自己的数据处理语言,Pig的数据处理过程要转化为MR来运行.2.Pig的数据处理语言是数据流 ...
- (转)python随机数用法
进行以下操作前先 import random ,导入random模块 1. random.seed(int) 给随机数对象一个种子值,用于产生随机序列. 对于同一个种子值的输入,之后产生的随机数序列也 ...
- .NET Runtime version 2.0.50727.xxx 执行引擎错误。 (Fatal Execution Engine Error)
如题问题困扰本人良久. 尝试VS2005.VS2008.VS2010均出现过次问题. 主要现象: 1. Window设计器会崩溃,直接挂掉.(当逐条注释掉一些静态构造函数内的代码是情况好转) 2. 发 ...
- thinkphp图像的裁剪、缩放、加水印
ThinkPHP 图片处理函数,需要文字水印字体,可在windows下 控制面板 > 大图标(右上角) > 字体 找到需要的字体 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
- Intellij IDEA Cannot resolve symbol XXX 问题解决办法汇总
maven项目遇到这类问题基本上是两方面的原因,类对应的依赖没有加载进来.编译器自身的设置和缓存问题. 解决第一类:1.检查项目的pom文件,是否必要的依赖都写清楚了: 2.是否使用自己的私有库,&l ...