The Register Resolve Release pattern by Mark Seemann
The subject of Dependency Injection (DI) in general, and DI Containers specifically, suffers from horrible terminology that seems to confuse a lot of people. Newcomers to DI often think about DI Containers as a sort of Abstract Factory on steroids. It's not. Nicholas Blumhardt already realized and described this phenomenon a couple of years ago.
The core of the matter is that as developers, we are extremely accustomed to thinking about components and services in terms of queries instead of commands. However, the Hollywood Principle insists that we should embrace a tell, don't ask philosophy. We can apply this principles to DI Containers as well: Don't call the container; it'l call you.
This leads us to what Krzysztof Koźmic calls the three calls pattern. Basically it states that we should only do three things with a DI Container:
- Bootstrap the container
- Resolve root components
- Dispose this container
This is very sound advice and independently of Krzysztof I've been doing something similar for years - so perhaps the pattern label is actually in order here.
However, I think that the pattern deserves a more catchy name, so in the spirit of the Arrange Act Assert (AAA) pattern for unit testing I propose that we name it the Register Resolve Release (RRR) pattern. The names originate with Castle Windsor terminology, where we:
- Register components with the container
- Resolve root components
- Release components from the container
Other containers also support the RRR pattern, but if we were to pick their terminology, it would rather be the Configure GetInstance Dispose (CGD) pattern (or something similar), and that's just not as catchy.
We can rewrite a previous example with Castle Windsor and annotate it with comments to call out where the three container phases occur:
private static void Main(string[] args) { var container = new WindsorContainer(); container.Kernel.Resolver.AddSubResolver( new CollectionResolver(container.Kernel)); // Register container.Register( Component.For<IParser>() .ImplementedBy<WineInformationParser>(), Component.For<IParser>() .ImplementedBy<HelpParser>(), Component.For<IParseService>() .ImplementedBy<CoalescingParserSelector>(), Component.For<IWineRepository>() .ImplementedBy<SqlWineRepository>(), Component.For<IMessageWriter>() .ImplementedBy<ConsoleMessageWriter>()); // Resolve var ps = container.Resolve<IParseService>(); ps.Parse(args).CreateCommand().Execute(); // Release container.Release(ps); container.Dispose(); }
Notice that in most cases, explicitly invoking the Release method isn't necessary, but I included it here to make the pattern stand out.
So there it is: the Register Resolve Release pattern.
Comments
However, a using block invokes Dispose, but not Release. Releasing an object graph is conceptually very different from disposing the container. However, in the degenerate case shown here, there's not a lot of difference, but in a server scenario where we use the container to resolve an object graph per request, we resolve and release many object graphs all the time. In such scenarios we only dispose the container when the application itself recycles, and even then, we may never be given notice that this happens.