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.