inavnacorp inavnacorp - 3 months ago 80
ASP.NET (C#) Question

c# asp.net core. How do I access datacontext from another class

I created class so I can query my data. If I do it in the controller class data context works, but if I do it in my created class it throws null error. It throws the following error:
Microsoft.Extensions.DependencyInjection.Abstractions.dll but was not handled in user code
My startup config:

public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);

services.AddDbContext<Abstractor_DataContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("ApplicationDatabase")));

//services.AddTransient(typeof(Abstractor_DataContext));


//Register your filter as a service (Note this filter need not be an attribute as such)
services.AddTransient<AppExceptionFilterAttribute>();

services.AddMvc();
}


My class function to access the datacontext

using Microsoft.Extensions.DependencyInjection;
public static IList<ApplicationInfo> TestDb()
{
//var options = _serviceProvider.GetService<Abstractor_DataContext>();
using (var context = _serviceProvider.GetService<Abstractor_DataContext>())
{
return context.ApplicationInfo.ToList();
}
}


var context is null. What am I missing? I am slowing learning DI.

Answer

As per the official documentation for new DB based ASP.net core project, first you need to create your Models and DbContext:

using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;

namespace EFGetStarted.AspNetCore.NewDb.Models
{
    public class BloggingContext : DbContext
    {
        public BloggingContext(DbContextOptions<BloggingContext> options)
            : base(options)
        { }

        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
    }

    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }

        public List<Post> Posts { get; set; }
    }

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }

        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
}

Then, register your context with dependency injection:

public void ConfigureServices(IServiceCollection services)
        {
            var connection = @"Server=(localdb)\mssqllocaldb;Database=EFGetStarted.AspNetCore.NewDb;Trusted_Connection=True;";
            services.AddDbContext<BloggingContext>(options => options.UseSqlServer(connection));

Then create your database using database migrations. Now you create your controller with your constructor taking your context as one of the parameter (Note BloggingContext context in the constructor parameter).

using EFGetStarted.AspNetCore.NewDb.Models;
using Microsoft.AspNetCore.Mvc;
using System.Linq;

namespace EFGetStarted.AspNetCore.NewDb.Controllers
{
    public class BlogsController : Controller
    {
        private BloggingContext _context;

        public BlogsController(BloggingContext context)
        {
            _context = context;
        }

        public IActionResult Index()
        {
            return View(_context.Blogs.ToList());
        }

        public IActionResult Create()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Create(Blog blog)
        {
            if (ModelState.IsValid)
            {
                _context.Blogs.Add(blog);
                _context.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(blog);
        }

    }
}

Using DbContext in any class is same using it in controller. You will need to register your class to Dependency injector. It is done in ConfigureServices method. This page from official docs is containing the details. Following are some of the examples to register the service class implementations:

services.AddScoped<ICharacterRepository, CharacterRepository>();
services.AddTransient<IOperationTransient, Operation>();
services.AddScoped<IOperationScoped, Operation>();
services.AddSingleton<IOperationSingleton, Operation>();
services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty));
services.AddTransient<OperationService, OperationService>();