Search code examples
ninjectninject-extensions

Ninject provider can't resolve types registered within a named scope


I am using the NamedScoped Ninject extension in an attempt to create object graphs that are constructed everytime a command handler is constructed by the container. In other words, I want a fresh object graph for every command that might get processed by its corresponding handler.

I have used the .DefinesNamedScope("TopLevelOrhcestrator") binding when registering my "command handlers" as they are the top level for command processing.

A type in this named scope needs to be injected with the result of a method call on a type already registered in this named scope. I thought the best way to do this would be with a ninject provider. Inside the provider I attempt to resolve the type in hopes I can call a method on it to pass into another object I am creating within this named scope. The problem I'm having is that when I ask the IContext for the instance inside the customer provider I get an exception that says "No matching scopes are available, and the type is declared InNamedScope(TopLevelOrchestrator).

context.Kernel.Get<TypeAlreadyRegisteredInScope>().MethodThatGetsAnotherDependency()

Is it possible to get types from the container inside a Ninject provider when they are registered inside a named scope?

EDIT

I apologize if the use case seems a bit odd, I am experimenting with some ideas about how to manage my units of work and other services/managers that may need a handle to the uow to complete a business usecase. I know its common for the unit of work to be "started" and then passed into all dependencies that may need to take part in a larger process. I was thinking I'd rather let my orchestrator take a unit of work factory so that it could deterministically destroy the UOW and it would be clear who the owner of a usecase is. What would get supplied to the managers/services would be a proxy to the unit of work that would be null until a real unit of work was started by the orchestrator. That's why I was attempting to link the proxy from the already registered type in my provider. This is all very experimental at this point and was testing some ideas.

I'd be happy to hear any further thoughts.


Solution

  • For MethodThatGetsAnotherDependency() to be able to .Get<>() an instance that is bound .InNamedScope(...) you will need to add the Context Preservation Extension.

    This is because NamedScope is adding a parameter to the request context of the binding that has .DefinesNamedScope(...). As soon as that request is over, that context and it's parameters are forgotten. Now with the ContextPreservation extension the context is kept and reused for late / factory creations (Func<>, interface factory with .ToFactory() binding...). It think it should also work with providers. If not, just switch to a factory instead of a provider.

    However i have to admit that i don't fully understand why/what you are trying to achieve. There might be simpler ways.