Structuremap ioc nested container / per request

Is there an extension point where we can create a new/nested ioc container on each request (the default way of how structuremap should be used, see http://structuremap.github.io/the-container/nested-containers/)

Thanks

Marco

If you’re looking for callbacks you can fire before and after each request you can use:

AppHost.PreRequestFilters
AppHost.OnEndRequestCallbacks

When you create the nested container what do you intend to do with it? add it to IRequest.Items then retrieve back later on in the pipeline from there?

It will depend on your advice.
So whenever we ask for an IContainer it should use the IContainer from the PreRequestFilter where the container was created as a NestedContainer.

In Core 1.1 you can use the IServiceScopeFactory
https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.extensions.dependencyinjection.iservicescopefactory

see StructureMap.Microsoft.DependencyInjection/src/StructureMap.Microsoft.DependencyInjection/StructureMapServiceScopeFactory.cs at 0d20c416c5423f5153a71589f5082a9b234b123c · structuremap/StructureMap.Microsoft.DependencyInjection · GitHub

A quote from the documentation of structuremap:

Why Nested Containers over HttpContext or ThreadLocal Scoping?
Why not just use HttpContext based lifecycles like we’ve always done in the past? Because HttpContext is not supported by any type of OWIN web host and will not be a part of ASP.Net vNext. Using a Nested Container per HTTP request is a better, lighterweight way to scope services to an HTTP request without coupling your code to what will soon be legacy ASP.Net runtime code.

You’re not going to be able to inject the nested Container to replace the AppHost Container, that’s a singleton container that’s pre hardwired to use the registered Container Adapter.

That’s why I asked, I only see you adding it to IRequest.Items then if you later want a dependency from the nested Container first check IRequest.Items for the nested container, if it’s there use it otherwise fallback to the AppHost container.

Ok, but then auto-resolving dependencies in services won’t work.

ps. The .NET Core is also using a nested container approach
https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.extensions.dependencyinjection.iservicescopefactory

Funq also has a CreateChildContainer method, but it’s not used in servicestack at the moment…

How does the current Funq container handle singleton registrations?

Not sure what you mean, it’s singleton by default and injects the same instance.

In the AppHost.Release every instance is diposed (if IDisposable), but maybe i’m missing something, still new to the codebase…

It doesn’t add singletons to the track disposables list.

ahh I missed this line

Adding a custom ContainerAdapter allows your services to resolve its dependencies from an alternative IOC, in this way they act like a dependency repository where the services are still registered in Funq but all their dependencies are resolved by the ContainerAdapter specified.

So you have to register the dependies in both Funq and the IContainerAdapter…

No, it’s saying Services (i.e classes inheriting ServiceStack’s Service) class is still registered in Funq, but all its dependencies are resolved through the Container Adapter.

It doesn’t affect where you want to register dependencies which you can choose to register in either Funq or your preferred IOC.

I’ve examined the code a bit more and have question
If you register an object in the container adapter (not in funq) with a singleton scope and it’s resolved by Funq, how does Funq know the scope of the resolved service (and/or nested resolved services)?

Funq can’t know the reuse scope in an external IOC.

But then it’s better to not use an external IOC/the adapter feature. Correct?

I’ve never needed anything more than Funq but it wont matter if your singletons don’t implement IDispose also your ContainerAdapter can implement IRelease to have the external IOC handle releasing their own dependencies.

One thing that i’m missing in Funq is the ResolveAll() method (and register more types implementing the same interface)

Another issue with funq is reported in this thread

RequestScope shouldn’t be used outside the HTTP worker request thread, e.g in background threads.

Correct, but what is the alternative in Funq for RequestScope?