8

我有另一个关于在 TinyIoc 中注册其他依赖项以在 NancyFX 中使用的新手问题。

运行应用程序时,我继续收到以下异常...

Unable to resolve type: AdvancedSearchService.Interfaces.IResponseFactory

Exception Details: TinyIoC.TinyIoCResolutionException: Unable to resolve type: AdvancedSearchService.Interfaces.IResponseFactory

Source Error: 
Line 25:             var container = TinyIoCContainer.Current;
Line 26: 
Line 27:             _responseFactory = container.Resolve<IResponseFactory>();
Line 28:           
Line 29: 

我目前正在错误地注册我的依赖项,但我似乎无法找出正确的方法。下面是我的自定义引导程序中的代码。另请注意,我目前没有调用 base.ConfigureRequestContainer 方法,因为我似乎无法弄清楚如何将当前上下文传递给它。

protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
    container.Register<IRavenSessionManager>(new RavenSessionManager());
    base.ConfigureApplicationContainer(container);

    ConfigureRequestContainer(container);
}


protected void ConfigureRequestContainer(TinyIoCContainer applicationContainer)
{
    var requestContainer = applicationContainer.GetChildContainer();
    requestContainer.Register<ISearchRepository>(new    SearchRepository(requestContainer.Resolve<IRavenSessionManager>().GetSession()));
    requestContainer.Register<IResponseFactory>(new ResponseFactory(requestContainer.Resolve<ISearchRepository>()));
    //base.ConfigureRequestContainer(requestContainer,[I NEED THE CONTEXT])
}

任何帮助将不胜感激......显然我的无知没有限制:)

4

1 回答 1

40

好的,不是 100% 确定从哪里开始.. 你不需要上下文,因为你做错了:-)

首先,您为什么要调用“配置请求容器”,为什么要创建子容器?你不要那样做:-)有两个范围,应用程序范围,通过覆盖ConfigureApplicationContainer配置,请求范围,通过覆盖ConfigureRequestContainer配置,你不要自己调用它们,你只需根据你想要的范围覆盖它们你的对象。

其次,默认的 Nancy 引导程序将在其默认的 ConfigureApplicationContainer 实现中“自动注册”一切。通过在您进行手动注册调用“base” ,您实际上是通过自动注册复制了您的原始注册。要么不要打电话给基地,要么在你手动注册之前打电话给它。而且,再次,不要从您的 ConfigureApplicationContainer 调用 ConfigureRequestContainer :-)

如果您不关心应用程序范围内的所有内容(因此 singetons 为每个请求获取相同的实例),那么您不需要任何这些,您可以只依赖自动注册。

您目前正在手动构建对象并将它们放入容器中,这似乎是一种相当奇怪的方法。通常,您只需注册类型并让容器在需要时处理实例化。

您没有覆盖 ConfigureRequestContainer,您只是在创建一个新方法(具有不同的签名)。

所以,你可能想要的是这样的:

protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
    base.ConfigureApplicationContainer(container);

    // Autoregister will actually do this for us, so we don't need this line,
    // but I'll keep it here to demonstrate. By Default anything registered
    // against an interface will be a singleton instance.
    container.Register<IRavenSessionManager, RavenSessionManager>();
}

// Need to override this, not just make a new method
protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context)
{
    // Get our session manager - this will "bubble up" to the parent container
    // and get our application scope singleton
    var session = container.Resolve<IRavenSessionManager>().GetSession();

    // We can put this in context.items and it will be disposed when the request ends
    // assuming it implements IDisposable.
    context.Items["RavenSession"] = session;

    // Just guessing what this type is called
    container.Register<IRavenSession>(session);

    container.Register<ISearchRepository, SearchRepository>();
    container.Register<IResponseFactory, ResponseFactory>();
}
于 2012-03-05T18:39:53.463 回答