简体   繁体   中英

Implement Repository and Db Context .Net Core Console Entity Framework with DI

I am creating a .NET Core 6 console application.

I have a repository class StorageCompetitorRepository that implements an interface IStorageCompetitorRepository .

The following is breaking and showing as null in Program.cs when I try to initialize:

  _storageCompetitorRepository = serviceProvider.GetService<StorageCompetitorRepository>();

The StorageCompetitorRepository class initializes the DbContext through the constructor.

Program.cs :

using Microsoft.Extensions.DependencyInjection;

class Program
{
     private static StorageCompetitorRepository _storageCompetitorRepository;
    
     static void Main(string[] args)
     {
         // configure services 
         var services = new ServiceCollection()
                    .AddTransient<IStorageCompetitorRepository, StorageCompetitorRepository>();
    
         // create service provider 
         var serviceProvider = services.BuildServiceProvider();
         _storageCompetitorRepository = serviceProvider.GetService<StorageCompetitorRepository>();
    
         bool runLoaderTool = true;

         while (runLoaderTool)
         {
             runLoaderTool = ChooseElasticIndexMenu(runLoaderTool, _storageCompetitorRepository);
         }
     }

     public static bool ChooseElasticIndexMenu(bool runLoaderTool, StorageCompetitorRepository storageCompetitorRepository)
     {
         // didn't add the full code that returns the boolean all you need
         // to know that the repo class method is called here 
         storageCompetitorRepository.GetStorageCompetitors();
     }
}

StorageCompetitorRepository :

public class StorageCompetitorRepository : IStorageCompetitorRepository
{
    string DatabaseServer = ConfigurationManager.AppSettings["DataBaseServer"];
    private readonly DevModelContext _devModelContext;
    public StorageCompetitorRepository(DevModelContext devModelContext) => _devModelContext = devModelContext;

    public List<storage_competitor> GetStorageCompetitors()
    {
        try
        {
            var ctx = _devModelContext.StorageCompetitors;
            var storageCompetitorList = (from sc in ctx
                                         where sc.active == true && sc.id_period == (from s in ctx select s).Max(s => s.id_period)
                                         select sc).Distinct()
                                         .OrderBy(sc => sc).ToList();
            var countStorageCompetitors = storageCompetitorList.Count();
            Console.WriteLine($"{countStorageCompetitors} Storage Competitors were found in SQL Server : {DatabaseServer} Database : Competitors");
 
            return storageCompetitorList; 
        }
        catch
        {
            return new List<storage_competitor>();
        }
    }
}

DevModelContext :

public class DevModelContext : DbContext
{
    string connectionString = ConfigurationManager.ConnectionStrings["connCompetitorsDev"].ConnectionString;

    public DevModelContext(DbContextOptions<DevModelContext> options) : base(options)
    {
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(connectionString);
    }

    public DbSet<storage_competitor> StorageCompetitors { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<storage_competitor>().ToTable("storage_competitor");
    }
}

Why is my initializing of the repo class showing as null when adding it as a transient service?

Any ideas or suggestions would be appreciated.

You are registering the interface but asking for the concrete implementation.

Here you are saying "When resolving a IStorageCompetitorRepository, give me the StorageCompetitorRepository"

var services = new ServiceCollection()
                .AddTransient<IStorageCompetitorRepository, StorageCompetitorRepository>();

Later you are trying to resolve the concrete implementation of the repository and the DI can't find it, since it has only been registered in the container as the interface, makes sense? Change this:

_storageCompetitorRepository = serviceProvider.GetService<StorageCompetitorRepository>();

To this:

_storageCompetitorRepository = serviceProvider.GetService<IStorageCompetitorRepository>();

If you WANT to be able to resolve the concrete implementation, you will need to register it.

AddTransient<StorageCompetitorRepository>();

You can then ALSO register it as the interface like this if you want to be able to resolve it via the interface as well.

AddTransient<IStorageCompetitorRepository, StorageCompetitorRepository>();

Or

AddTransient<IStorageCompetitorRepository>(x => x.GetRequiredService<StorageCompetitorRepository);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM