Which IoC container is better with Prism.Forms

Martin Robins picture Martin Robins · Apr 27, 2017 · Viewed 12k times · Source

I am in the start of a new Prism.Forms project and I was wondering which of the various IoC containers (Autofac, Dryloc, Ninject or Unity) would be best to move forward with.

I do not know if this is true, but I read somewhere that Unity is no longer under active development and since this and MEF are the only IoC containers I have ever used I am unsure as to whether it is the way to go.

Meanwhile, I know little or nothing about Autofac, Dryloc or Ninject.

Please be objective in any advise, providing reasons why you feel one is better than the others rather than simply "I use xxx"; I would like to make an informed decision.

Answer

Dan Siegel picture Dan Siegel · Apr 28, 2017

The best I can do is to layout the facts as they currently stand.

NOTE: A lot has changed since I first answered this in 2017. The information below has continued to be updated and should help you as you look to make decisions on your projects. Do take note however that you do also now have the ability to utilize the Prism.Container.Extensions as this provides support for abstracting many highly powerful registration methods including factories, and the ability to register a single implementation as a singleton for different services. Additional containers may be added there. Additional documentation for this can be found at https://prismplugins.com

Supported Containers

These are containers that ship officially from the Prism team

DryIoc

This is the container I use and recommend the most. It's under active development, it's very fast, and works well with the current release of Prism. Also important is that when I have had questions or issues the maintainer has been very quick to address the issue or answer the question I had. Dadhi is also very good at proactively providing enhancements for the Prism integration. It's for all of these reasons I continue to recommend the container. Unlike Unity the API tends to be very stable and I have not yet had an issue with updating DryIoc beyond what a particular release of Prism was targeting.

Unity Container

Not to be confused with the Unity Game Development Platform. This is the most popular container due to it being the container that Brian has used for years and it being the first (and for a long time only) container available in the Templates. It had gone quite some time without being maintained, however the project does have a new maintainer. It's worth noting that there were a number of breaking changes in Unity 5 which makes upgrading to Unity 5 with Prism 6.3 an impossibility. Prism has however updated to Unity 5 across all platforms in Prism 7. Unity is also about average with regards to its benchmark performance. For those upgrade to Prism 7 from Prism 6.X note that you should uninstall any references to Unity or the Common Service Locator and then update Prism.Unity.Forms which now targets the Unity.Container NuGet package instead of the Unity NuGet package. You should also beware that targeting a newer version of Unity than what Prism is built against may break your application as Unity has introduced a number of breaking changes without explanation or documentation from Minor Patch to Minor Patch.

Unofficially Supported

These are containers that have an unofficial package available. These may or may not work for you and are at your own risk.

Microsoft.Extensions.DependencyInjection

Prism requires certain features such as mutability and named services which are not supported by the Microsoft DependencyInjection pattern. There is however an implementation that provides universal support for all Prism applications/platforms from the Prism.Container.Extensions project.

End of Life / Deprecated Containers

While these containers have been used in many projects over the years the following containers are No Longer supported by the Prism team.

Autofac

Despite being popular, is a container I generally would advise against using. People seem to be very confused by the API. In Prism 6.3 it suffered from a really poor implementation. Sadly the Autofac team decided very strongly in order to improve performance that they would make the container immutable. Prism officially dropped support for this container as of Prism 7.1.

Ninject

Ninject was long one of the least utilized container. This was dropped from Prism.Forms in 7.0 as the team moved to support netstandard. While Ninject 3.3 does technically ship with a netstandard2.0 api, it's is not compatible with Xamarin targets. It is also currently in a very unhealthy state having the latest 3.3 release from November 2017 and the latest 4.0 preview from August 2016.

UPDATE

Well worth noting is that starting with Preview 5 of Prism 7 we have abstracted the containers. This will ultimately make it far easier to switch between the container of your choosing as the API is exactly the same with regards to how to register your services and Views. You will still have access to the Container and in the case of Autofac the ContainerBuilder through extension methods, so that you can accomplish more complex registrations.

// Prism 6.X way of Registering Services
protected override void RegisterTypes()
{
    // Container Specific Registrations

    // Autofac
    Builder.RegisterType<DebugLogger>().As<ILoggerFacade>().SingleInstance();

    // DryIoc
    Container.Register<ILoggerFacade, DebugLogger>(reuse: Reuse.Singleton,
                                                   ifAlreadyRegistered: IfAlreadyRegistered.Replace);

    // Ninject
    Container.Bind<ILoggerFacade>().To<DebugLogger>().InSingletonScope();

    // Unity
    Container.RegisterType<ILoggerFacade, MCAnalyticsLogger>(new ContainerControlledLifetimeManager());
}

// Unified API in Prism 7
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.RegisterSingleton<ILoggerFacade, DebugLogger>();
}

It is also important to remember that while Prism's IoC abstractions have made it easier to have a more unified API, this does not remove your ability to interact directly with the underlying Container. To access the underlying container you simply need to call the GetContainer extension method and you will be able to perform any more complex action that is not directly supported by Prism's IoC abstractions.

UPDATE 2

Prism 7.2 has introduced some API changes around the IoC Abstractions. Notably by and large these changes should not affect most users. However you may experience binary incompatibilities if using other libraries that reference older versions of Prism.

The IoC changes include:

  • A Fluent API
  • An ability to check if a service is registered
  • Added methods to allow both transient and singleton services to be Named Services
  • Added ability to resolve a service with specified instances.