Home > Mobile >  Unable to create an object of type 'PrattleContext' when trying to connect to value from a
Unable to create an object of type 'PrattleContext' when trying to connect to value from a

Time:08-01

My application is layered like so

API -appsettings.json

DAL -configs -appsettings -contexts -mydbcontext

I am simply trying to pass my connection stirng in app settings to my dbcontext through projects and run migrations.

When I hit dotnet ef migrations add initial

I get the error

    PM> dotnet ef migrations add changing
    Build started...
    Build succeeded.
    Unable to create an object of type 'PrattleContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
    PM> 

My program.cs file (in api project)

using Microsoft.EntityFrameworkCore;
using prattle.Data.Configs;
using prattle.Data.Contexts;

var builder = WebApplication.CreateBuilder(args);


// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

//db
builder.Services.AddDbContext <PrattleContext> (option =>
    option.UseNpgsql(builder.Configuration.GetConnectionString("prattleDatabase")));

builder.Services.Configure<AppSettings>(builder.Configuration.GetSection("ConnectionStrings").GetSection("prattleDatabase"));


builder.Services.AddOptions();
var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

appsettings.json (in api project)

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "prattleDatabase": "Host=localhost; Database=prattle; Username=develop; Password=develop123;"
  }
}

configs/appsettings ( in data layer )

namespace prattle.Data.Configs
{
    public class AppSettings
    {
        public string prattleDBConnectionString { get; set; }
    }
}

contexts/prattlecontext ( in data layer )

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using prattle.Data.Configs;
using prattle.Model.Models;

namespace prattle.Data.Contexts
{
    public class PrattleContext : DbContext 
    {
        private IOptions<AppSettings> _appsettings;

        public PrattleContext()
        {

        }


        public PrattleContext(IOptions<AppSettings> appsettings)
        {
            _appsettings = appsettings;
        }


        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {

            var dbConnectionInfo = _appsettings.Value.prattleDBConnectionString;

            optionsBuilder.UseNpgsql(dbConnectionInfo);

        }

        public DbSet<User> Users { get; set; }

        public DbSet<Message> Messages { get; set; }
    }
}

I'm guessing the issue is in my program.cs file, but I can't work out why?

CodePudding user response:

First of all builder.Services.Configure<AppSettings>(builder.Configuration.GetSection("ConnectionStrings").GetSection("prattleDatabase")); will not work as you expect, prattleDBConnectionString will be null. To make it work you need to match name of json property and property of class which represents settings:

public class AppSettings
{
    public string prattleDatabase { get; set; }
}

Then to bind it correctly you need to use only ConnectionStrings section:

builder.Services.Configure<AppSettings>(builder.Configuration.GetSection("ConnectionStrings"));

Also note that the setup via options you are using is not an idiomatic way to manage EF Core context, usually you need only one enter image description here

And the Startup project selected in the solution explorer (select the API one).

If you still want to use dotnet ef tool you may need to specify next options:

Option Short Description
--project <PROJECT> -p Relative path to the project folder of the target project. Default value is the current folder.
--startup-project <PROJECT> -s Relative path to the project folder of the startup project. Default value is the current folder.

With -p set to the project containing the context and -s set to the API project with connection string.

  • Related