PowerMan2015
PowerMan2015

Reputation: 1418

DBContext between business layers

I've created two projects:

Web Project, that contains all the viewmodels/data/controllers etc. And a Web Api project to allow form capture.

I simply want to capture the data in the web Api and save it to the database where it will become accessible to the front end.

I am experiencing an issue initialzing the DBcontext within the Api controller and need help.

namespace ZebraCRM.API2.Controllers

    {
        [Route("api/[controller]")]
        public class LeadsController : Controller
        {
        private readonly ApplicationDbContext _context;

        public LeadController(ApplicationDbContext context)
        {
            _context = context;
        }


            // POST api/values
            [HttpPost]
            public void Post(Lead formData)
            {
                formData.DateCreated = DateTime.Now;

                _context.Lead.Add(formData);
                _context.SaveChanges();
        }
    }

The above idea was taken from the controller in the main web project, but is obviously not the right approach in this situation.

the debug outputs the following

System.InvalidOperationException: Unable to resolve service for type 'ZebraCRM.Web.Data.ApplicationDbContext' while attempting to activate 'ZebraCRM.API2.Controllers.LeadsController'.

Upvotes: 1

Views: 89

Answers (1)

mason
mason

Reputation: 32703

The framework doesn't know how to constructor a LeadController because it doesn't know how to satisfy the ApplicationDbContext context parameter when it calls the constructor. To solve this, you could simply assign the value as part of your constructor, eliminating the parameter.

namespace ZebraCRM.API2.Controllers
{
    [Route("api/[controller]")]
    public class LeadsController : Controller
    {
        private readonly ApplicationDbContext _context;

        public LeadController()
        {
            _context = new ApplicationDbContext();
        }        

        // POST api/values
        [HttpPost]
        public void Post(Lead formData)
        {
            formData.DateCreated = DateTime.Now;        
            _context.Lead.Add(formData);
            _context.SaveChanges();
        }
    }
}

Or, if you do want to leave the constructor parameter in place, you'll need a DI container such as AutoFac or Ninject. If you're new to DI, I suggest you watch this video. When you set things up for Dependency Injection, you will basically pass something to the framework that says "When constructing an object that needs an X, here's how you give it an X". This allows you to better follow SOLID principles. An object can demand an IRepository (an interface) and as part of your DI setup you can say "when an object demands an IRepository, I want to pass it a SqlServerRepository (which would implement IRepository)". Then if you later decided to switch to MySQL, you could modify the setup to use a MySqlRepository instead of SqlServerRepository, without needing to modify anything about the controller, since the controller would use the repository via the interface.

Upvotes: 1

Related Questions