Registering dependencies within TinyIOC for use in NancyFX

16,951

Ok, not 100% sure where to start.. you don't need the context because you're doing it wrong :-)

Firstly, why are you calling "configure request container" at all, and why are you creating a child container? You don't do that :-) There are two scopes, application scope, configured by overriding ConfigureApplicationContainer, and request scope, configured by overriding ConfigureRequestContainer, you don't call them yourself, you just override them depending on how you want to scope your objects.

Secondly, the default Nancy bootstrapper will "autoregister" everything it can in its default implementation of ConfigureApplicationContainer. By calling "base" after you've made a manual registration you are effectively copying over your original registration by autoregister. Either don't call base, or call it before you do your manual registrations. And, again, don't call ConfigureRequestContainer from your ConfigureApplicationContainer :-)

If you don't care about everything being application scoped (so singetons get the same instance for each request) then you don't need any of this, you can just rely on autoregister.

You're currently constructing your objects manually and putting them into the container, that seems a rather odd way to do it. Normally you'd just register the types and let the container handle instantiating as and when it needs to.

You're not overriding ConfigureRequestContainer, you are just creating a new method (with a different signature).

So, what you probably want is something like:

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>();
}
Share:
16,951
TheWeekendDeveloper
Author by

TheWeekendDeveloper

Updated on July 26, 2022

Comments

  • TheWeekendDeveloper
    TheWeekendDeveloper almost 2 years

    I have another newbie question regarding registering additional dependencies within TinyIoc for use within NancyFX.

    I am continuing to get the following exceptions when running the application...

    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: 
    

    I am currently registering my dependencies incorrectly, but I cannot seem to figure out the correct way. Below is my code within my custom bootstrapper. Also note that I am not currently calling the base.ConfigureRequestContainer method because I cannot seem to figure out how to get the current context to pass into it.

    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])
    }
    

    Any help would really be appreciated...apparently my ignorance has no limits :)

  • TheCodeJunkie
    TheCodeJunkie over 12 years
    Nancy also does auto resolution of constructor dependencies in modules (and other types) so you never should use TinyIoCContainer.Current and resolve directly from that. Simply add a dependency to your constructor and off you go! Thanks
  • TheWeekendDeveloper
    TheWeekendDeveloper over 12 years
    I must say this...for someone having the avatar of GrumpyDev, I was expecting a lot more :( and not so many :). I know my code had to of confused the crap out of you, so thanks for your patience.
  • TheWeekendDeveloper
    TheWeekendDeveloper over 12 years
    Btw: that fixed it like a charm. You recognized what I failed to recognize, and that was the different signature of the ConfigureRequestContainer method. I first tried to override it just like you have in your solution, but failed to realize I was using the old signature. Because Nancy did not recognize the old signature, I created created my private method out of desperation :). Oddly enough I eventually added the base.ConfigureRequestManager(contianer,context) to my private method, but failed to make the connection. My brain was fried by that point :).
  • TheWeekendDeveloper
    TheWeekendDeveloper over 12 years
    BTW, I love the the registration syntax that you added register<IType, ConcreteType>(). I was using that based on your documentation at first, but changed it later on...again out of desperation and ignorance. Thanks again for the help, and keep up the great work on TinyIoc and NancyFx. I am truly digging it!
  • TheWeekendDeveloper
    TheWeekendDeveloper over 12 years
    Thanks for the advice CodeJunkie. I will make sure not to do that in the future either.
  • c0bra
    c0bra about 10 years
    Thanks for this answer. I was having trouble getting my mocks registered in my test bootstrapper and moving them from ApplicationStartup to ConfigureApplicationContainer fixed it.