0

I currently do have the following setup these are the different projects
Project.DAL: Data Access Layer
Project.BLL: Business Logic Layer
Project.Core: Interfaces, Models
Project.API: Web API
Project.Console: Simple .NET console app that

in Project.DAL I did setup the db context

 public class AppDbContext : DbContext
    {
        public DbSet<Role> Roles { get; set; }
        public DbSet<User> Users { get; set; }
        public AppDbContext(DbContextOptions<AppDbContext> options)
            : base(options)
        { }

        
       
    }

while I did setup within Project.API all the Dependencies Injections

            services.AddTransient<IUserService, UserService>();
            services.AddDbContext<AppDbContext>(options =>
            {
                options.UseSqlServer(Configuration.GetConnectionString("Default"),x => x.MigrationsAssembly("Project.DAL"));
            });

when I try to run Program.cs in Project.Console

  class Program
    {
        private static AppDbContext _appDbContext; 
        static void Main(string[] args)
        {
            
             _appDbContext.Users.ToList();
        }
}

Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
any idea ?
Thanks In Advance.

jeankhawand
  • 106
  • 8

1 Answers1

3

You need to do the configurations for all the entry points.

  1. Entry point is yout API
  2. The second entry point is your console application

So you need to modify your main function:

  class Program
    {
        private static AppDbContext _appDbContext; 
        static void Main(string[] args)
        {
            // _appDbContext is not initialized right now
            // Even if you configure the injection here the _appDbContext will not be initialized.
             _appDbContext.Users.ToList();
        }
}

Check the net core console app dependency injection guide

using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace ConsoleDI.Example
{
    class Program
    {
        static Task Main(string[] args)
        {
            using IHost host = CreateHostBuilder(args).Build();

            ExemplifyScoping(host.Services, "Scope 1");
            ExemplifyScoping(host.Services, "Scope 2");

            return host.RunAsync();
        }

        static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((_, services) =>
                    services.AddTransient<ITransientOperation, DefaultOperation>()
                            .AddScoped<IScopedOperation, DefaultOperation>()
                            .AddSingleton<ISingletonOperation, DefaultOperation>()
                            .AddTransient<OperationLogger>());

        static void ExemplifyScoping(IServiceProvider services, string scope)
        {
            using IServiceScope serviceScope = services.CreateScope();
            IServiceProvider provider = serviceScope.ServiceProvider;

            OperationLogger logger = provider.GetRequiredService<OperationLogger>();
            logger.LogOperations($"{scope}-Call 1 .GetRequiredService<OperationLogger>()");

            Console.WriteLine("...");

            logger = provider.GetRequiredService<OperationLogger>();
            logger.LogOperations($"{scope}-Call 2 .GetRequiredService<OperationLogger>()");

            Console.WriteLine();
        }
    }
}

The key code in the example above is this:

provider.GetRequiredService<OperationLogger>();

This is the one that creates the OperationLogger from the configured DI container.

You should create the AppDbContext DI rules, build CreateHostBuilder(args).Build(); and the create the instance as shown above.

Athanasios Kataras
  • 25,191
  • 4
  • 32
  • 61