The Art of Lean
Now that everyone knows just how fast Hiro can be, the next question you might be asking yourself is, "What features will it support?"
The simplest answer that I can give is that Hiro is that it will implement as little features as possible--in fact, Hiro will implement so little features that it might turn away your traditional "dynamic" IOC user. Here's the features that Hiro will implement:
-Named/Anonymous Static Component Registration. This means that you'll be able to register your services using a service name, service type, and the implementing type.
-Convention Over Configuration for Registration and Injection.. In addition to its support for programmatic registration, Hiro will be able to scan your assemblies and automatically infer:
- The list of available services
- The list of concrete types that implement those services
- The list of properties that can be injected
- The constructors that will be used for constructor injection
- The services that will be injected into each parameter during a constructor injection call.
The most interesting part about this is the amount of work that will take to do this sort of registration. Take a look at this example:
var loader = new DependencyMapLoader();
var map = loader.LoadFrom(AppDomain.CurrentDomain.BaseDirectory, "Yourlibrary.dll");
IContainerCompiler compiler = new ContainerCompiler();
var microContainer = compiler.Compile(map);
Believe it or not, this is the only code that you need to use to configure the dependencies for any assembly of any given size. What makes this even more interesting is the fact that all of this is done statically at (container) compile time, not runtime. This means that unlike the current generation of IOC containers, Hiro will not waste any time trying to rediscover your configuration, and based on the benchmark results from my previous post
, the performance numbers are nothing short of being dramatically one-sided.
Aside from performance, however, Hiro has to be able to create both Transient (that is, plain old object instances created with the New operator) and Singleton instances.
Hiro will implement both property and constructor injection by default. What makes this even more interesting is that like everything else with Hiro, all property and constructor injection calls will all be precompiled into IL, meaning that there will be no performance issues when using Hiro.
Each Hiro-compiled container instance will not have any private local data (or even shared data) that will distinguish it from another compiled container of the same type. This means that you can scale Hiro's compiled containers across multiple cores AND multiple threads without using a single semaphore, mutex, or lock statement (in C#)."But wait, your container isn't a REAL container until you implement feature X!"
Some would argue that Hiro would have to implement a minimum "baseline" feature set in order to be considered a "commercial" quality IOC container. However, my counterargument there is that it's this same "fat feature" mindset that got these IOC containers (including LinFu) into this speed problem in the first place. Secondly, if you're experienced enough about IOC to understand the significance of what Hiro does and give an opinion about what features might be missing, then it's safe to assume that you're a user that falls into at least one of the two following categories:
- You've probably written at least one IOC container framework, or
- You already are comfortable with an existing IOC container framework (such as Castle, Ninject, AutoFac, Unity, StructureMap, LinFu, etc) and you know enough to customize it to your needs.
Assuming that you're an IOC container author, it would be pointless for me to implement something in Hiro that you've probably rolled into your own framework, and given that you're skilled enough to write your own framework, I assume that it would be practically trivial for you to plug Hiro into your own framework and reap the performance benefits, and there's clearly no reason to reinvent the wheel here if you somehow did a better job than I did in implementing "feature X".
Now, if you think you're a user that falls into the second category, there's a good chance that you've pretty much decided to stick to the favorite framework of your choice, and like the other IOC container authors, there's really nothing that I can do for you unless you decide to plug in Hiro into your favorite container.
So between these two types of users, who do you think Hiro is written for?
Here's my answer: Neither one of them.
Hiro is written for the average developer who wants to get started with an IOC container and doesn't have time to "geek out" over the latest and greatest features of an IOC container framework. Given that there are probably far better IOC container developers than myself, I've pretty much decided to skip the "my container is better than your container" religious wars and focus on what really matters: the end users.
The Pareto Pleasure Principle
Hiro doesn't need to implement 80% of the expected features of an IOC container in order to be useful--instead, it only has to implement the other 20% of the overall features that (in my opinion) people will actually use. In the end, if I can help those people get their jobs done in the simplest possible way without forcing them to wade through the "awesomeness" of my framework, then I would call Hiro a success, and at the end of the day, that's really all that matters.