Question

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.

Was it helpful?

Solution

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...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top