Steven points out two ways to explore to reach a solution :
- Don't check for null, rather use a Null Object Pattern
- Wrap the
IHandler<T>
with a decorator and inject the IInjector in the decorator
The second option was not desirable since it would have loaded the handlers with a responsibility they didn't have to know about. Ideally I should move this injection behavior into its own independent interceptor and let it live entirely there without any other code knowing about it. I may do that later.
The first point though is the way to go. Null Object Pattern decreases the complexity of my method and leaves it much clearer than with a null check. All i have to do is create a NopInjector
class and declare it as the default value for the factory.
Don't try to create an injector depending on a base object:
public class NopInjector : IInjector<object>
{
public void InjectStuff(object target, string stuff) { }
}
Rather create a generic injector and register it as an open generic component
public class NopInjector<T> : IInjector<T>
{
public void InjectStuff(T target, string stuff) { }
}
// registration
_container.Register(
Component.For(typeof(IInjector<>))
.ImplementedBy(typeof(NopInjector<>))
.IsDefault());
_container.Register(
Classes
.FromAssemblyInThisApplication()
.BasedOn(typeof(IInjector<>))
.WithService.AllInterfaces());
Now if Castle.Windsor can resolve a specific IInjector<Command>
it will, else it will return the NopInjector
. No more null check:
private static void DoActualWork<T>(T command)
{
injectorFactory.GetInjector<T>().InjectThings(command, "");
// calling handlers...
}