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.
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.