2

afBedSheet文档说“过滤器可用于解决诸如授权之类的交叉问题。” 并显示此代码段:

@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服务,但不知道在哪里或如何。谁能告诉我怎么做,好吗?

线程局部变量:
  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
  网络会话:060f9951-41f1-e500-0fc2-0019b971d079
[05:27:18 05-Nov-13] [err] [web] 内部错误处理:/info
  afIoc::IocErr:没有依赖匹配类型 mt::AuthFilter。
Ioc 操作跟踪:
  [1] 通过类型 'afBedSheet::HttpPipeline' 定位依赖
  [2] 创建真正的服务 'HttpPipeline'
  [3] 通过构建器方法“afBedSheet::BedSheetModule.buildHttpPipeline”创建服务“HttpPipeline”
  [ 4] 确定 afBedSheet::HttpPipeline buildHttpPipeline(afBedSheet::HttpPipelineFilter[] filters, afIoc::PipelineBuilder bob, afIoc::Registry reg) 的注入参数
  [ 5] 寻找 afBedSheet::HttpPipelineFilter[] 类型的依赖
  [6] 收集 afBedSheet::HttpPipelineFilter[] 类型的 ORDERED 配置
  [ 7] 确定 sys::Void 的注入参数
我的身份验证过滤器)
  [ 8] 寻找 mt::AuthFilter 类型的依赖
堆栈跟踪:
    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)
    并发::Actor._dispatch (Actor.java:228)
    并发::Actor._work (Actor.java:199)
    并发::ThreadPool$Worker.run (ThreadPool.java:255)
4

1 回答 1

1

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

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

    authFilter := AuthFilterImpl()

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

如果AuthFilter依赖于其他服务(例如,它有用 注释的字段@Inject),那么afIoc应该为您构建实例。和对象为此提供了一个方便的OrderedConfig方法:MappedConfigautobuild()

    authFilter := conf.autobuild(AuthFilterImpl#)

如果你想AuthFilter被注入到其他服务中,或者你想为它做出贡献,那么它需要被定义为一个afIoc服务。使用bind()你的方法AppModule来做到这一点:

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

然后可以将其参数注入到contribute方法中,就像您在示例中所做的那样:

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

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

有关更多详细信息,请参阅afIoc - 定义服务。BedSheetModule也可能是 afIoc 示例的一个很好的参考。

于 2013-11-04T20:17:48.517 回答