如何使用afBedSheet将自定义过滤器添加到HttpPipeline?

时间:2013-11-04 19:51:14

标签: fantom afbedsheet

afBedSheet documentation表示“过滤器可用于解决交叉问题,例如授权。”并显示此代码段:

@Contribute { serviceType=HttpPipeline# }
static Void contributeHttpPipeline(OrderedConfig conf, AuthFilter myAuthFilter) {
  conf.addOrdered("AuthFilter", myAuthFilter, ["after: BedSheetFilters"])
}

我正在尝试实现一个AuthFilter(现在是一个虚拟的但是要演变成一个真正的AuthFilter)但是我无法让它工作:

using afBedSheet

const mixin AuthFilter : HttpPipelineFilter { }

internal const class AuthFilterImpl : AuthFilter {

    internal new make(|This|in) { in(this) }

    override Bool service(HttpPipeline handler) {
        echo("Dummy AuthFilter invoked!")
        return handler.service
    }
}

我可以成功构建项目,但是当我运行它并调用任何HTTP服务时,我得到以下错误。我相信我必须声明或注释我的AuthFilter作为afIoc服务,但不知道在哪里或如何。有谁能告诉我怎么样?

Thread Locals:
  ThreadStash.01.BedSheetModule.0017.perThreadState: fan.afIoc.ModuleServices@1ab5e0b
  ThreadStash.01.HttpRequest.0001.headers: fan.afBedSheet.HttpRequestHeaders@1ab6087
  afIoc::ThreadStash.counter: 13
  web.req: fan.wisp.WispReq@4e62cc
  web.res: fan.wisp.WispRes@387bc2
  web.session: 060f9951-41f1-e500-0fc2-0019b971d079
[05:27:18 05-Nov-13] [err] [web] Internal error processing: /info
  afIoc::IocErr: No dependency matches type mt::AuthFilter.
Ioc Operation Trace:
  [ 1] Locating dependency by type 'afBedSheet::HttpPipeline'
  [ 2] Creating REAL Service 'HttpPipeline'
  [ 3] Creating Service 'HttpPipeline' via a builder method 'afBedSheet::BedSheetModule.buildHttpPipeline'
  [ 4] Determining injection parameters for afBedSheet::HttpPipeline buildHttpPipeline(afBedSheet::HttpPipelineFilter[] filters, afIoc::PipelineBuilder bob, afIoc::Registry reg)
  [ 5] Looking for dependency of type afBedSheet::HttpPipelineFilter[]
  [ 6] Gathering ORDERED configuration of type afBedSheet::HttpPipelineFilter[]
  [ 7] Determining injection parameters for sys::Void contributeHttpPipeline(afIoc::OrderedConfig conf, mt::AuthFilter
myAuthFilter)
  [ 8] Looking for dependency of type mt::AuthFilter
Stack Trace:
    afIoc::Utils.stackTraceFilter (Utils.fan:63)
    afIoc::RegistryImpl.dependencyByType (RegistryImpl.fan:243)
    afBedSheet::BedSheetWebMod.onService (BedSheetWebMod.fan:34)
    wisp::WispActor.doService (WispActor.fan:197)
    wisp::WispActor.process (WispActor.fan:78)
    wisp::WispActor.receive (WispActor.fan:48)
    concurrent::Actor._dispatch (Actor.java:228)
    concurrent::Actor._work (Actor.java:199)
    concurrent::ThreadPool$Worker.run (ThreadPool.java:255)

1 个答案:

答案 0 :(得分:1)

AuthFilter需要被声明为服务 - 您可以在contrib()方法中新建一个实例:

@Contribute { serviceType=HttpPipeline# }
static Void contributeHttpPipeline(OrderedConfig conf) {

    authFilter := AuthFilterImpl()

    conf.addOrdered("AuthFilter", authFilter, ["after: BedSheetFilters"])
}

如果AuthFilter依赖于其他服务(例如,它的字段标注为@Inject),那么afIoc应该为您构建实例。 OrderedConfigMappedConfig对象只有一个方便的autobuild()方法:

    authFilter := conf.autobuild(AuthFilterImpl#)

如果您希望将AuthFilter注入其他服务,或者您想要为其做出贡献,则需要将其定义为afIoc服务。使用bind()中的AppModule方法执行此操作:

static Void bind(ServiceBinder binder) {
    binder.bind(AuthFilter#, AuthFilterImpl#)
}

然后可以将参数注入到contrib方法中,就像在示例中一样:

@Contribute { serviceType=HttpPipeline# }
static Void contributeHttpPipeline(OrderedConfig conf, AuthFilter authFilter) {

    conf.addOrdered("AuthFilter", authFilter, ["after: BedSheetFilters"])
}

有关详细信息,请参阅afIoc - definingServices。对于afIoc示例,BedSheetModule也可能是一个很好的参考。