How do I inject my dbContext class using Unity? I can\'t just create a Interface like for my other \"normal\" classes? What should I do with my RequestContext class and what
I'm usually solving this with a DbContextFactory
. This would allow you to create the context when needed and also dispose it when you're done.
public interface IDbContextFactory
{
IdentityDbContext GetContext();
}
public class DbContextFactory : IDbContextFactory
{
private readonly IdentityDbContext _context;
public DbContextFactory()
{
_context = new RequestContext("ConnectionStringName");
}
public IdentityDbContext GetContext()
{
return _context;
}
}
This factory can easily be injected. You can see a more complete example here: Repository Pattern universal application
With the factory you will also have the option to create the DbContext in constructor or in the method. When using Unity I recommend you to do as little as possible in the constructor, as Unity will resolve the entire chain for you. This means that the DbContext will be created every time the repository is resolved. This would require the class that injects the repository also needs to dispose the repository (which in turn should dispose the DbContext), and what happens when two classes are using the same repository instance? This can obviously be solved with lifetimemanagers and good programming practices, but I find it more elegant to simply open and close the context when needed.
Example for usage in a method:
using (var context = _dbContextFactory.GenerateContext())
{
return context.Requests.FirstOrDefault(x => x.Id == foo);
}
And a more complete example for your repository:
public class RequestRepository
{
private IDbContextFactory _contextFactory;
public RequestRepository(IDbContextFactory contextFactory)
{
// DbContext will not be created in constructor, and therefore your repository doesn't have to implement IDisposable.
_contextFactory= contextFactory;
}
public Request FindById(int id)
{
// Context will be properly disposed thanks to using.
using (var context = _dbContextFactory.GenerateContext())
{
return context.Requests.FirstOrDefault(x => x.Id == id);
}
}
}
And when you're creating your interface for your context I can also recommend you to change DbSet
to IDbSet
to allow easier unit testing. Example of interface for DbContext
.
public interface IDbContext : IDisposable, IObjectContextAdapter
{
IDbSet Requests { get; set; }
IDbSet Records { get; set; }
int SaveChanges();
DbSet Set(Type entityType);
DbSet Set() where TEntity : class;
}
If your're looking to inject the DbContext
in the constructor you could also take a look at the Unit of Work-pattern, which wraps the DbContext
and allows several classes to use the same context over a specific lifetime (eg a request). One may argue that EF already implements the Unit of Work-pattern, but I leave that discussion for another time. Here's a couple of examples:
http://www.codeproject.com/Articles/741207/Repository-with-Unit-of-Work-IoC-and-Unit-Test
Onion Architecture, Unit of Work and a generic Repository pattern