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
This site has a GREAT tutorial on how to get Unity working: https://medium.com/aeturnuminc/repository-pattern-with-dependency-injection-mvc-ef-code-first-91344413ba1c
I'm going to assume you have Entity Framework installed, know how to create a viewmodel and put on attributes using System.ComponentModel.DataAnnotations
and System.ComponentModel.DataAnnotations.Schema
namespaces, and I'll assume you can create a view and controller. None of that is really relevant until the end, anyway.
You have to get the NuGet package Unity to install these references:
My DataContext (Model1.cs) looks like this:
public partial class Model1 : DbContext
{
public Model1()
: this(true)
{ }
public Model1(bool enableLazyLoading = true)
: base("name=Model1")
{
// You can do this....
//Database.SetInitializer(new CreateDatabaseIfNotExists());
//this.Configuration.LazyLoadingEnabled = false;
// or this...
Database.SetInitializer(null);
this.Configuration.ProxyCreationEnabled = false;
((IObjectContextAdapter)this).ObjectContext.ContextOptions.ProxyCreationEnabled = enableLazyLoading;
((IObjectContextAdapter)this).ObjectContext.ContextOptions.LazyLoadingEnabled = enableLazyLoading;
}
// All my tables and views are assigned to models, here...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove();
base.OnModelCreating(modelBuilder);
}
}
My Repository (DataRepository.cs) looks like this:
namespace WeeklyReport.Repository
{
public class DataRepository : IDataRepository
{
private bool disposing;
private readonly Model1 context;
public virtual void Dispose()
{
if (disposing)
{
return;
}
disposing = true;
if (context != null)
{
context.Dispose();
}
}
public void SaveChanges()
{
context.SaveChanges();
}
public DataRepository()
{
context = new Model1();
context.Configuration.ProxyCreationEnabled = false;
}
public IEnumerable GetAllMetrics()
{
var myMetrics = context.MetricsTable; // put into ReportVM and return, etc.
}
// etc., etc.
}
}
My Interface (IDataRepository.cs) looks like this:
namespace WeeklyReport.Repository
{
public interface IDataRepository
{
void SaveChanges();
IEnumerable GetAllMetrics();
}
}
My UnityConfig.cs in the App_Start folder looks like this:
using Microsoft.Practices.Unity;
using WeeklyReport.Repository;
using System.Web.Mvc;
using Unity.Mvc3;
namespace WeeklyReport
{
public class UnityConfig
{
public static void RegisterContainer()
{
var container = new UnityContainer();
//ensure the repository is disposed after each request by using the lifetime manager
container.RegisterType(new HierarchicalLifetimeManager());
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
}
}
And you have to call RegisterContainer
in Global.ascx.cs inside Application_Start
:
UnityConfig.RegisterContainer();
From a controller, it gets a handle to IDataRepository
:
using WeeklyReport.Repository;
namespace WeeklyReport.Controllers
{
public class ReportController : Controller
{
private readonly IDataRepository repository;
public ReportController(IDataRepository repository)
{
this.repository = repository;
}
public ActionResult Index()
{
List reportVM = new List();
var reqs = repository.GetAllMetrics();
// iterate reqs and put into reportVM, etc.
return View(reportVM);
}
}
}
And you can call repository
as if it was the real class - you're just getting an interface instance to it.