How to inject my dbContext with Unity

后端 未结 3 473
Happy的楠姐
Happy的楠姐 2021-01-12 01:23

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

3条回答
  •  清酒与你
    2021-01-12 01:36

    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:

    • Microsoft.Practices.Unity
    • Unity.Mvc3 (or 4 or 5)

    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.

提交回复
热议问题