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.
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.
Related
I’ve upgraded my project today to Prism 6.3.0 and Unity 5.3.1. Before that, I had Prism 5 and Unity 4.
Now I’m running into problems with the Prism.Unity.UnityBootstrapper: it seems that the Container field is still a Microsoft.Practices.Unity.IUnityContainer instead of Unity.IUnityContainer.
I had hoped that the upgrade would cleanly cut all references to Microsoft.Practices.Unity off of my project, but it seems that I’m still forced to use the “old” Prism library, at least in parts.
Why does this situation arise, and what do I do to make it right? Am I missing something?
Unity 5.x is not supported in Prism yet. So, you will have to stick with 4.x until that happens. My understanding is, it is a goal of the team to support Unity 5.x in Prism 7 and up.
As you mentioned in your comment, there has been a lot of talk in the GitHub repo for Prism about the changes that came along with Unity 5. Glad to know that there are people willing to take on Unity, and move it forward, though.
I've read some things about .NET Standard and .NET Core, and generally they seem to say something like "This is the new way to do things, and here are the advantages and disadvantages."
What I haven't seen is a good, clear explanation of what was wrong with the status quo, such as .NET Standard and .NET Core were even necessarily. To really judge what I should use these for, it would be helpful to know why they exist at all.
Can someone give a clear (and not necessarily concise!) explanation of (a) what problem .NET Standard and .NET Core are intended to solve, and (b) how they solve it?
.NET Standard is a set of library contracts. Each version includes all the contracts of the previous version - so everything in netstandard1.4 is in netstandard1.5 for example.
.NET Core is an implementation of .NET Standard (and some extra functionality) which runs on Windows, Linux and OSX.
Biggest problems they solve:
Not having a Microsoft-provided/supported toolchain and runtime on Linux/MacOSX. Saying that you could only run .NET-based server code on Windows or Mono was simply untenable.
The Portable Class Library mess with hundreds of different profiles giving partially-overlapping API surfaces to target.
PCLs in particular were very hard to work with for class library authors such as myself. The mess came about because there were multiple efforts to bring a .NET runtime to different devices without enough coordination to provide a coherent API surface to target.
Now multiple vendors can target particular versions of .NET Standard, and anything targeted to that version or higher should work. For example, my Noda Time library targets netstandard1.3. Suppose a new mobile phone vendor comes out with a completely new implementation of .NET, with a completely new kind of application - but says they support netstandard2.0. That's fine - a user of that new platform will still be able to install the Noda Time NuGet package and (implementation bugs aside, of course) they'll be able to use it. I don't need to know that the platform even exists.
I am currently working on a RIA project in flex, but have recently come across openlaszlo. It seems a lot of large projects have chosen it over flex, such as the streaming music service Pandora. I'm interested in why. So far the biggest advantage I have seen is that it has an abstraction layer for support of flash 6,7, 8, 9 and dhtml and has been in development for a longer time (so possibly more stable).
Has anyone had much experience using both, or just openlaszlo even? is the support for dhtml and older flash versions really that big of an advantage with the popularity of flash 9 these days? Might this just be because of many developers are already comfortable with javascript/ajax? Besides language preferences, why openlaszlo and not flex?
Thanks for any tips!
Ryan
When companies like Pandora chose OpenLaszlo, Flex was still a commercial product (even the compiler). The Flex versions 1.0 and 1.5 were not very stable, and only with the 2.0 release of Flex the platform got a lot more stable. Macromedia upset a lot of developers, since Flex 2.0 was no compatible with 1.5, and all applications had to be rewritten for the new release. In that situation quite a few companies thought that OpenLaszlo is not a bad choice.
The most powerful feature of OpenLaszlo is the LZX language. The language supports classes, animation of any numeric property, constraints using a attribute="${}" syntax, mixin support, datasets with datapath (xPath syntax based) mapping. Some of the key developer of the LZX langauge had been working on Apple's Dylan language before, and a lot of the powerful concepts of Dylan have made it into the LZX language.
I've done both OpenLaszlo and Flex development. Flex has excellent tooling support by various IDE vendors. But the ActionScript 3 language can be very limiting, as in Java you spend a lot of time thinking about your class model. OpenLaszlo emphasizes instance based development (very fast for prototyping, while it's still possible to build very complex applications with 100k+ lines of LZX code). The largest OpenLaszlo applications I'm aware of are Laszlo Webtop (120K+ lines of LZX code), and IBM Websphere Commerce Edition (http://ibm.co/Kid5tc). I've heard that other companies have created equally large applications using OpenLaszlo.
Since version 4.2 OpenLaszlo integrates the Flex SDK. The OpenLaszlo compiler generates the LZX code into JavaScript 2, and then into ActionScript 3 code. If you compile an application to both DHTML and SWF10+, you can profit from the better type checking of the Flex compiler, even if your application will only be deployed for the DHTML/HTML5 runtime.
OpenLaszlo is very stable. The last major release (4.0) has been in March 2007, although the OpenLaszlo team considered the 4.2 release to be equal to a major version upgrade, since it added the ActionScript 3 and SWF9 support to the platform. 4.2 was released in December 2008, the current stable release is the 4.9 version - although many community members and Laszlo are already using OpenLaszlo 5.0 (trunk, unreleased) in production.
After Adobe's announcement to contribute the Flex SDK to the Apache Foundation (now an Apache Foundation Incubator project), Adobe announced that they had been working on a cross-compilation feature for the next generation Flex compiler called "FalconJS". Adobe said as well, that FalconJS (which will probably be contributed to Apache Flex in Q4 2012) will not be able to cross-compile existing Flex applications into JavaScript. A simple list example of FalconJS (as demoed in December 2011) generated into 5 MB of uncompressed JavaScript code, wich could be boiled down to 2.5 MB using the Google Closure compiler's advanced mode. A similar OpenLaszlo example in the DHTML runtime compiles to less than 750k of JavaScript code.
I think your term of 'a lot of large projects' is very relative. Yes, some large companies have used it, but I don't consider any of them large projects. If you look at all of them in the OpenLaszlo showcase, they seem fairly simple interfaces to me. Also note that OpenLazslo compiles Flash, not Flex and associated framework.
To me, OpenLaszlo is an alternative for creating simple RIAs in a way that the end code can be compiled into Flash or Javascript. Haxe is another alternative to this, and I think it does a better job than OpenLaszlo.
With that said, there's a problem with these "generic" write once, compile to Flash/Javascript framework; it doesn't harness any of the power/advantages of each specific platform. Flash is constantly changing and so is Javascript with the addition of html5 tags and css3. If you ever have experience in both, you'll notice that they're very different in the way they do things and on algorithm might work well with Flash, might not with Javascript.
My point being, if you are to choose a technology, go for the one that's more appropriate. If your project has a need to have both Javascript and Flash, then this might be a good choice, but remember that you'll then be losing the 'power' of each. For instance, Flex has a very good skinning architecture and a set of tools that is essential for enterprise development. Javascript can do some pretty neat stuff with selectors, css3, and some other frameworks like jQuery.
In my experience, post compilers like OpenLaszlo eliminates those strengths. Plus, if there's a new thing that comes outs (like say, hardware accelerated video/3d for javascript/flash), you have to wait for the people at OpenLazslo to update before you can use it (if they use it).
I started developing RIAs with OpenLaszlo as it offered a cross browser run-anywhere kind of framework. The user experience delivered with it was also very good.
I moved to Flex (when it was in Beta) because:
Every capability of OpenLaszlo was available in Flex.
Flex had an extra advantage as it was a supported commercial product from a leading digital media content creation company Macromedia & later acquired by Adobe.
Flash Builder (a.k.a Flex Builder) built on Eclipse provided a good development productivity improvement. (so spending one time license fee on it is not at all an issue)
Above all Flex had better server-side integration / remoting capability.
Flex had plenty of tutorials & sample codes so ramping up a new developer was very easy.
Now Flex is also community driven open source project under Apache Software Foundation
OpenLaszlo now provides an extra feature over Flex (until FalconJS cross compiler is released) that it can run both Flash & Ajax runtime environment with a single code base .
But still Flex has an added advantage of having very good development environment (with integration to other Adobe designer tools) and good server side integration capability so for enterprise applications, Flex is a clear winner.
I'm developing an application that makes use of Qt and OpenGL, using Qt Creator and QGLWidget subclassing.
My application has a user base that has a higher than average proportion of older hardware, which is why I need it to run on machines with graphics cards supporting OpenGL 2.1 only - or, in other words, I cannot rely on anything newer than 2.1 being present.
I am worried about unknowingly using OpenGL functionality that was introduced after 2.1. Is there any way I can configure OpenGL to "only" support 2.1, so that I would get a runtime error if I do something I shouldn't be doing? Or, failing that, what is the best practice to ensure compatibility?
The only thing you need to worry about is not creating a OpenGL-3 core profile context, and only to use functions found in the OpenGL-2.1 specification.
Since creating a OpenGL-3 core context requires you to jump some hoops, you're not running into problems there. The system may give you something newer than OpenGL-2.1 but as long as you don't use any functionality not found in the 2.1 specification document you're fine. You'll have to use the extension mechanism, to actually get the functionality on Windows; OpenGL-2.1 is technically a list of extensions made official functionality, so carefully read the Appendix of the specification, where the functionality that formerly were extensions are explicitly mentioned.
Are child containers supported together with Unity in ver 2.5 of NServiceBus ?
See http://andreasohlund.net/2010/10/12/support-for-child-containers-in-nservicebus/
http://tech.groups.yahoo.com/group/nservicebus/message/9391 .
When I use StructureMap as my IoC-container it works great and I don’t need to any special configuration. But when I use Unity as my IoC-container it won’t work at all.
Unity supports child containers, see http://msdn.microsoft.com/en-us/library/ff650130.aspx.
Child container support is only moving forward in v3.0 (currently the master branch). It was enough of a breaking change to the v2.0-v2.5 branch that we didn't include it.
If you'd like to contribute some code to the project to enable child-container support in Unity, send me a pull request on the NServiceBus project on GitHub, and I'll pull in your changes.