Use a different IoC provider then the built-in when using MvvmCross

As I wrote in an earlier post, MvvmCross has IoC built-in. If you for some reason want to use a different IoC provider then the built-in when using MvvmCross you can write your own provider and use for example Autofac or TinyIoC. This post will show you how to use Autofac.

I create an own project (of type Portable Class Library) so I don't have to reference Autofac in my core project. I can have it in my client project but then I can't reference it from other client projects.

In my Autofac resolver I have to implement the IMvxIoCProvider interface and the class has to inherit from MvxSingleton if it should work.

public class AutofacMvxProvider : MvxSingleton, IMvxIoCProvider
    {
        private IContainer _container;

        public AutofacMvxProvider(IContainer container)
        {
            _container = container;
        }

        public void CallbackWhenRegistered(Type type, Action action)
        {
            _container.ComponentRegistry.Registered += (sender, args) => {
                if(args.ComponentRegistration.Services.OfType().Any( x => x.ServiceType == type))
                {
                    action();
                }
            };
        }

        public void CallbackWhenRegistered(Action action)
        {
            CallbackWhenRegistered(typeof(T), action);
        }

        public bool CanResolve(Type type)
        {
            return _container.IsRegistered(type);
        }

        public bool CanResolve() where T : class
        {
            return _container.IsRegistered();
        }

        public object Create(Type type)
        {
            return Resolve(type);
        }

        public T Create() where T : class
        {
            return Resolve();
        }

        public object GetSingleton(Type type)
        {
            return Resolve(type);
        }

        public T GetSingleton() where T : class
        {
            return Resolve();
        }

        public object IoCConstruct(Type type)
        {
            return Resolve(type);
        }

        public T IoCConstruct() where T : class
        {
            return Resolve();
        }

        public void RegisterSingleton(Type tInterface, Func theConstructor)
        {
            var builder = new ContainerBuilder();
            builder.Register(x => theConstructor()).As(tInterface).AsSelf().SingleInstance();
            builder.Update(_container);
        }

        public void RegisterSingleton(Func theConstructor) where TInterface : class
        {
            var builder = new ContainerBuilder();
            builder.Register(x => theConstructor()).As().AsSelf().SingleInstance();
            builder.Update(_container);
        }

        public void RegisterSingleton(Type tInterface, object theObject)
        {
            var builder = new ContainerBuilder();
            builder.RegisterInstance(theObject).As(tInterface).AsSelf().SingleInstance();
            builder.Update(_container);
        }

        public void RegisterSingleton(TInterface theObject) where TInterface : class
        {
            var builder = new ContainerBuilder();
            builder.RegisterInstance(theObject).As().AsSelf().SingleInstance();
            builder.Update(_container);
        }

        public void RegisterType(Type tFrom, Type tTo)
        {
            var builder = new ContainerBuilder();
            builder.RegisterType(tTo).As(tFrom).AsSelf();
            builder.Update(_container);

        }

        public void RegisterType(Type t, Func constructor)
        {
            var builder = new ContainerBuilder();
            builder.Register(x => constructor()).As(t).AsSelf();
            builder.Update(_container);
        }

        public void RegisterType(Func constructor) where TInterface : class
        {
            var builder = new ContainerBuilder();
            builder.Register(x => constructor()).As().AsSelf().SingleInstance();
            builder.Update(_container);
        }

        public void RegisterType()
            where TFrom : class
            where TTo : class, TFrom
        {
            var builder = new ContainerBuilder();
            builder.RegisterType().As().AsSelf();
            builder.Update(_container);
        }

        public object Resolve(Type type)
        {
            return _container.Resolve(type);
        }

        public T Resolve() where T : class
        {
            return _container.Resolve();
        }

        public bool TryResolve(Type type, out object resolved)
        {
            return _container.TryResolve(type, out resolved);
        }

        public bool TryResolve(out T resolved) where T : class
        {
            return _container.TryResolve(out resolved);
        }
    }

To use your own IoC provider you have to override the CreateIocProvider method in your Setup class.

protected override Cirrious.CrossCore.IoC.IMvxIoCProvider CreateIocProvider()
{
            var builder = new ContainerBuilder();

            builder.RegisterType().As();
          
            var container = builder.Build();

            return new AutofacMvxProvider(container);
}

  9/3/2014 - 7:34 PM
An error has occurred. This application may no longer respond until reloaded. Reload 🗙