Question

I have a IDataContext interface implemented by a InMemoryDataContext and MyApplicationDataContext. This is consumed by all of my repositories which are defined as BananaRepository : IBananaRepository and take the data context in their constructor:

interface IDataContext {}
class InMemoryDataContext : IDataContext {}
class MyApplicationDataContext : IDataContext {}

interface IBananaRepository {}
class BananaRepository : IBananaRepository 
{
    public BananaRepository(IDataContext dataContext) {}
}

So far my consumers of the interfaces and services are ASP.NET MVC controllers, synchronous commands and queries. NInject is configured in my Web project and IDataContext is bound to MyApplicationDataContext with InRequestScope().

 kernel.Bind<IDataContext>().To<MyApplicationDataContext>().InRequestScope();
 kernel.Bind<IBananaRepository>().To<BananaRepository>();

I have reached the point in the evolution of my project where I want to start adding asynchronous processing (commands, events+handlers, etc). The problem I am facing is that for those I need to get a transient IDataContext (new one each time) but the binding is already set-up for a IDataContext instance per request for my controllers.

Consider this simple scenario, where my DoSomethingAsyncCommand will execute on a new thread:

class DoSomethingAsyncCommand : IAsyncCommand<TArgs>
{
    public DoSomethingAsyncCommand(IBananaRepository repository) {}

    public bool Execute(TArgs args) {}
}

I want when NInject instantiates a class implementations of IAsyncCommand the IBananaRepository (and all my other repositories) to be initialized with a new instance of IDataContext rather than the one for the web request to be reused (effectively I want for IAsyncCommand my IDataContext to be bound as InTransientScope())

How can I do that?

P.S: I am using the CommonServiceLocator rather than the Ninject kernel directly to instantiate IAsyncCommand instances.

Was it helpful?

Solution

Look at https://github.com/ninject/ninject/blob/master/src/Ninject/Planning/Bindings/BindingConfigurationBuilder.cs

There you find IsAnyAnchestorNamed. You can use that same loop and combine it with the condition you find in WhenInjectedInto and call it from a custom When.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top