Home > OS >  ASP.NET Core 6 Background Service Entity Framework Injection
ASP.NET Core 6 Background Service Entity Framework Injection

Time:06-24

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

  • Related