Castle.Windsor: optional resolution of component from a typed factory

坚强是说给别人听的谎言 提交于 2019-12-02 04:51:17

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...
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!