Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

C# Inject DbContext to Class

I work in an environment where applications are typically already stood up and so I have never had to setup the "guts" of a C# web application. However, wanting to learn this, I decided to create a .NET 6 Web API project, a .NET 6 Class Library project, and a .NET 4.8.1 Database project.

My Web API project only has the controllers using the MVC pattern. My Class Library project is my "domain" layer where I have my models, services (aka domains), and database queries. My Database project allows me to manage my database schema and any migrations.

In my class library I have setup my DbContext as well as a query, service, and model for an "Example" entity (which only has id and name fields) that look like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

// DbContext
using MyApplication.Domain.Models;
using Microsoft.EntityFrameworkCore;
namespace MyApplication.Domain
{
    public class MyApplicationDbContext : DbContext
    {
        public DbSet<ExampleModel> Examples { get; set; }

        MyApplicationDbContext(DbContextOptions<MyApplicationDbContext> options) : base(options) { }
    }
}

// Query
using MyApplication.Domain.Models;
namespace MyApplication.Domain.Queries
{
    public class ExampleQuery
    {
        private readonly MyApplicationDbContext _context;
        public ExampleQuery(MyApplicationDbContext context)
        {
            _context = context;
        }

        public IEnumerable<ExampleModel> Query(Dictionary<string, dynamic>? filter = null)
        {
            filter ??= new Dictionary<string, dynamic>();
            var records = _context.Examples.AsQueryable();
            if (filter.ContainsKey("ExampleId"))
            {
                Guid exampleId = filter["ExampleId"];
                records = records.Where(record => record.ExampleId == exampleId);
            }
            return records;
        }
    }
}

// Service
using MyApplication.Domain.Exceptions;
using MyApplication.Domain.Models;
using MyApplication.Domain.Queries;
namespace MyApplication.Domain.Services
{
    public class ExampleService
    {
        private readonly ExampleQuery _exampleQuery;

        public ExampleService(ExampleQuery exampleQuery)
        {
            _exampleQuery = exampleQuery;
        }

        public IEnumerable<ExampleModel> GetAll()
        {
            return _exampleQuery.Query();
        }

        public ExampleModel Get(Guid id)
        {
            var records = _exampleQuery.Query(new Dictionary<string, dynamic>
            {
                { "ExampleId", id }
            });

            if (!records.Any())
            {
                throw new NotFound404("There aren't any records by that id");
            }
            if (records.Count() > 1)
            {
                throw new Conflict409("There are multiple records with that id");
            }
            return records.Single();
        }
    }
}

// Model
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MyApplication.Domain.Models
{
    public class ExampleModel
    {
        [Key]
        [Required]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public Guid ExampleId { get; set; }

        [Required]
        [MaxLength(64)]
        public string? ExampleName { get; set; }
    }
}

Then in my Web API project, I setup the dependency injection using the following in my Program.cs (using top level statements):

builder.Services.AddDbContext<MyApplicationDbContext>(dbContextOptions => dbContextOptions.UseSqlServer(builder.Configuration.GetValue<string>("ConnectionStrings:MyApplication")));
builder.Services.AddSingleton<ExampleQuery>();
builder.Services.AddSingleton<ExampleService>();

The issue is that my Web API project fails to run because ExampleQuery injects the MyApplicationDbContext with the error:

A suitable constructor for type
‘MyApplication.Domain.MyApplicationDbContext’ could not be located.
Ensure the type is concrete and services are registered for all
parameters of a public constructor.

Again, I’m not very familiar with setting up projects from scratch so I’m not certain how to resolve this dependency issue.

>Solution :

Your MyApplicationDbContext has private constructor, make it public

public class MyApplicationDbContext : DbContext
{
    public DbSet<ExampleModel> Examples { get; set; }

    public MyApplicationDbContext(DbContextOptions<MyApplicationDbContext> options) : base(options) { }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading