Castle.Windsor:来自类型化工厂的组件的可选解析

2023-12-01

我有一个带有 Castle.Windsor 的 WCF 服务设置;消息到达调度程序,调度程序将它们发送到正确的组件(基本上是一个IHandler<Message>消息是一个查询)。

然而,在某些情况下,在处理程序可以采取行动之前还需要进行一项额外的操作;该消息必须用来自其他地方的数据来完成。我想要的是检查是否存在适合我的消息类型的注入器,如果存在,则运行它。

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");
}

这背后的原因是,在未来的某个时刻,有人可能会创建一个带有IInjector<Message>我想在未来的某个时间挑选它;但目前它还不存在。

当找不到组件时,是否可以让类型化工厂返回 null 而不是抛出异常ComponentNotFoundException?

EDIT

正如与@Steven 讨论的那样,我将回答我自己的问题,以便编译是什么引导我找到解决方案和我找到的解决方案。首先我们重申一下问题

我有一个 WCF 服务,基本上遵循 Krzysztof Koźmic 在中描述的结构本文

但是,在调用处理程序之前,我希望有一个可选操作,其中传入的消息将在需要时进行修改。

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();
    }
}

我在使用 InjectorFactory 时遇到了问题;当我要求它找到一个不存在的组件时,它会抛出一个ComponentNotFoundException。我希望工厂能够识别出没有组件并简单地返回 null。


Steven 指出了两种探索解决方案的方法:

  • 不要检查 null,而是使用空对象模式
  • 包裹住IHandler<T>使用装饰器并将 IInjector 注入装饰器中

第二种选择并不可取,因为它会给处理程序带来他们不必知道的责任。理想情况下,我应该将此注入行为移至其自己的独立拦截器中,并让它完全存在于其中,而无需任何其他代码了解它。我可能会稍后再做。

第一点是要走的路。空对象模式降低了我的方法的复杂性,并且比空检查更清晰。我所要做的就是创建一个NopInjector类并将其声明为工厂的默认值。

Don't尝试根据基础对象创建注入器:

public class NopInjector : IInjector<object>
{
    public void InjectStuff(object target, string stuff) { }
}

而是创建一个通用注入器并将其注册为开放通用组件

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());

现在如果 Castle.Windsor 可以解析特定的IInjector<Command>会的,否则会返回NopInjector。不再进行空检查:

private static void DoActualWork<T>(T command)
{
    injectorFactory.GetInjector<T>().InjectThings(command, "");
    // calling handlers...
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Castle.Windsor:来自类型化工厂的组件的可选解析 的相关文章

随机推荐