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.
You can waste days evaluating IOC containers. The top ones are quite similar. There is not much in this, but the best ones are StructureMap and AutoFac.
It's not so much that there is a Unity container, but 'Unity' is the name of a particular Dependency Injection (DI) container. Prism also comes with MEF and supports any other DI container. Unity just came first.
Prism has always been built around Dependency Injection. This helps you to architect apps that are maintainable and testable and help you reduce or eliminate your dependence on Static and circular references.
The most valuable benefit of using an IoC container is that you can have a configuration switch in one place which lets you change between, say, test mode and production mode. For example, suppose you have two versions of your database access classes...
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
These are containers that ship officially from the Prism team
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.
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.
These are containers that have an unofficial package available. These may or may not work for you and are at your own risk.
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.
While these containers have been used in many projects over the years the following containers are No Longer supported by the Prism team.
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 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.
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.
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With