I\'m using ASP.NET Core, and its builtin DI container. I\'m using a third-party library (NLog) which I can\'t change.
My Foo class has a dependency (by
You don't want to inject your IoC container anywhere. That's a bad practice that allows for sloppy coding, and makes unit testing harder, amongst many other reasons.
Instead introduce a factory that can be injected and create a context on demand:
public interface IDbContextFactory<TContext>
{
TContext Create();
}
public class DbContextFactory<TContext> : IDbContextFactory<TContext>
where TContext : DbContext
{
private readonly Func<TContext> _contextCreator;
public DbContextFactory(Func<TContext> contextCreator)
{
_contextCreator = contextCreator;
}
public TContext Create()
{
return _contextCreator();
}
}
Now if you inject this into your Foo:
public class Foo
{
private readonly IDbContextFactory<MyContext> _contextFactory;
public Foo(IDbContextFactory<MyContext> contextFactory)
{
_contextFactory = contextFactory;
}
public void bar() {
{
using (var context = _contextFactory.Create())
{
// use your freshly instantiated context
}
}
}
Any decent dependency injection framework can resolve the Func<TContext> parameter of the DbContextFactory, and pass a func there that creates an instance per request.
Addendum to @CodeCaster's excellent solution.
It's important to change Func<Dependency> to Func<Owned<Dependency>>. Otherwise the container won't return new instances each time, even though you're using a delegate factory.
Probably has something to do with the fact that a long-lived component (singleton) depends on a short-lived component (per-transaction). The Func<> prevents the captive dependency bug, but for the factory to also give you new instances each time, it needs to be Owned<>.
I don't understand why, and it seems counter-intuitive, but that's how it works.