Occasionally I find myself in a situation where I need to resolve a service only if a certain condition is met. For example, a user might select to send an email or an sms notification. I would like to lazy load the email or sms service depending on what the user chooses so that I don't have to load both of them and waste resources (what if there were, for example, 10 options for the user...?).
The problem I have is with using the container outside of my bootstrap code (I dont want my code dependent on th container). I can't seem to find a way around using the container for lazy loading services (unless I create the needed services by hand and do all the DI manually). Is this a situation where the rules can be bent or is there a better way of doing it?
If you are using Castle Windsor 3.0 or newer, you can use lazy resolving.
See What's new in Windsor 3 for more details.
Registration process changes a bit (new component loader must be registered).
After that, you are just registering components as always, but resolve dependencies as Lazy<T>
instead of T
. Until you won't access .Value
property of your Lazy<T>
, dependency will not be resolved, so you can pass few lazily evaluated objects and access only the one you will need and when you need.
If you have more options to the user, maybe you should consider creating some sort of abstract factory interface. You would then register and resolve only this factory and the factory itself would create appropriate service for sending notifications (be it a mail or a sms or any other option). Implementation of the factory can be coded by hand or Castle Windsor can you with that (I think from version 3.0).
Often when I do use such factory, I implement it by hand and pass container as it's dependency, so only factory implementation depends on my container.