I'm using .NET 6 and Entity Framework.
I want use Entity Framework in my background service, but my EF variable (IAppRepository
) is null. And I get this error:
System.NullReferenceException:'Object reference not set to an instance of an object.'
How can I inject the DbContext
?
My code:
Program.cs
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddHostedService<APIService>();
})
.Build();
await host.RunAsync();
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<DataContext>(x=>
x.UseSqlServer(builder.Configuration.GetConnectionString("BankSearchConnection")));
builder.Services.AddScoped<IAppRepository, AppRepository>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
app.MapFallbackToFile("index.html"); ;
app.Run();
APIService.cs (my background service)
public class APIService : BackgroundService
{
private readonly ILogger<APIService> _logger;
public APIService(ILogger<APIService> logger)
{
_logger = logger;
}
private IAppRepository _appRepository;
public APIService(IAppRepository appRepository)
{
_appRepository = appRepository;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Banka verileri güncellendi! Saat: {time}", DateTimeOffset.Now);
BankAPI();
_logger.LogInformation("Garanti Bankası geçti");
await Task.Delay(180000, stoppingToken);
}
}
private void BankAPI()
{
string uri = "https://apis.garantibbva.com.tr:443/loans/v1/paymentPlan";
var client = new RestClient(uri);
var request = new RestRequest(Method.POST);
request.AddHeader("apikey", "l7xx8af86c14ea7e44e0ab3fbfcc6137ae09");
request.AddQueryParameter("loanType", "1");
request.AddQueryParameter("campaignCode", "BankSearch");
request.AddQueryParameter("loanAmount", "10000");
IRestResponse response = client.Execute(request);
int dueNum = 3;
float monthlyAnnualCostRate = JObject.Parse(response.Content)["data"]["list"]
.Where(p => (int)p["dueNum"] == dueNum)
.Select(p => (float)p["monthlyAnnualCostRate"])
.FirstOrDefault();
_logger.LogInformation("Garanti Bankası Response: {monthlyAnnualCostRate}", monthlyAnnualCostRate);
AddKredi("Garanti Bankası",1,monthlyAnnualCostRate);
}
private void AddKredi(string bankaAdi, int krediVadeKodu, float krediFaizi)
{
Kredi kredi = new Kredi(bankaAdi, krediVadeKodu, krediFaizi);
_appRepository.Add(kredi); //I take _apprepository=null error in this line
_appRepository.SaveAll();
}
}
IAppRepository.cs
public interface IAppRepository
{
void Add<T>(T entity);
bool SaveAll();
}
AppRepository.cs
public class AppRepository : IAppRepository
{
private DataContext _context;
public AppRepository(DataContext context)
{
_context = context;
}
public void Add<T>(T entity)
{
_context.Add(entity);
}
public bool SaveAll()
{
return _context.SaveChanges() > 0;
}
}
CodePudding user response:
Change your constructor to use only one instead of two
public class APIService : BackgroundService
{
private readonly ILogger<APIService> _logger;
private readonly IAppRepository _appRepository;
public APIService(IAppRepository appRepository, ILogger<APIService> logger)
{
_appRepository = appRepository;
_logger = logger;
}
}
In your code the first constructor will be resolved by Dependency Injection so the exception message is correct your _appRepository
is null
.
You can also find more/other details here