Регистрация зависимостей в TinyIOC для использования в NancyFX - PullRequest
8 голосов
/ 05 марта 2012

У меня есть еще один вопрос новичка о регистрации дополнительных зависимостей в 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])
}

Любая помощь будет по достоинству оценена ... очевидно, мое невежество не имеет границ:)

1 Ответ

38 голосов
/ 05 марта 2012

Хорошо, не на 100% уверен, с чего начать .. вам не нужен контекст, потому что вы делаете это неправильно: -)

Во-первых, почему вы вообще вызываете "настроить контейнер запросов"и почему вы создаете дочерний контейнер?Вы этого не делаете :-) Есть две области: область приложения, настроенная с помощью переопределения ConfigureApplicationContainer, и область запроса, настроенная путем переопределения ConfigureRequestContainer, вы не вызываете их сами, вы просто переопределяете их в зависимости от того, как вы хотите охватитьваши объекты.

Во-вторых, загрузчик Нэнси по умолчанию будет «автоматически регистрировать» все, что может, в реализации по умолчанию ConfigureApplicationContainer.Позвонив «base» после , вы сделали ручную регистрацию, вы фактически копируете оригинальную регистрацию с помощью авторегистрации.Либо не звоните в базу, либо позвоните, прежде чем делать ручную регистрацию.И, опять же, не вызывайте ConfigureRequestContainer из вашего ConfigureApplicationContainer: -)

Если вас не волнует, что все находится в области приложения (так что для каждого запроса у 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>();
}
...