I have a WCF service setup with Castle.Windsor; messages arrive to a dispatcher that send them to the right component (basically a IHandler<Message>
with message being a query).
However in some cases there is one additional before the handler can act; the message must be completed with data coming from someplace else. What i want is to check whether there exists an injector for the type of my message and if one exists, run it.
IInjector<Message> Injector = InjectorFactory.RetrieveInjector<Message>();
if (Injector != null)
{
Logger.InfoFormat("IInjector<{0}> OK", input.GetType().Name);
Injector.InjectCode(input, "Data coming from somewhere else");
}
The reasoning behind this is that at some future point somebody may create a plugin with a IInjector<Message>
and I want to pick it at a future time; but at the moment it doesn't exist.
Is it possible to have a typed factory returning null when a component is not found instead of throwing a ComponentNotFoundException
?
EDIT
As discussed with @Steven I will be answering my own question in order to compile what lead me to the solution and the resolution i found. First let's restate the problem
I have a WCF service basically following the structure described by Krzysztof Koźmic in this article
However, before calling the handlers i wanted to have an optionnal operation where the incoming message would be modified if needed.
private static void DoActualWork<T>(T command)
{
IInjector<T> Injector = injectorFactory.GetInjector<T>();
if (Injector != null) { Injector.InjectThings(command, ""); }
var handlers = factory.GetHandlersForCommand(command);
foreach (var handler in handlers)
{
handler.Execute();
}
}
I was having a problem with the injectorFactory; when i asked it to find a non-existing component it would throw a ComponentNotFoundException
. What i would have liked is for the factory to recognize there was no component and simply return a null.
Steven points out two ways to explore to reach a solution :
IHandler<T>
with a decorator and inject the IInjector in the decoratorThe 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:
Rather create a generic injector and register it as an open generic component
Now if Castle.Windsor can resolve a specific
IInjector<Command>
it will, else it will return theNopInjector
. No more null check: