Реализовать репозиторий и контекст базы данных .Net Core Console Entity Framework с DI

Я создаю консольное приложение .NET Core 6.

У меня есть класс репозитория StorageCompetitorRepository, который реализует интерфейс IStorageCompetitorRepository.

Следующее ломается и отображается как null в Program.cs, когда я пытаюсь инициализировать:

  _storageCompetitorRepository = serviceProvider.GetService<StorageCompetitorRepository>();

Класс StorageCompetitorRepository инициализирует DbContext через конструктор.

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");
    }
}

Почему моя инициализация класса репо отображается как null при добавлении его в качестве временной службы?

Любые идеи или предложения будут оценены.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
33
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы регистрируете интерфейс, но запрашиваете конкретную реализацию.

Здесь вы говорите: «При разрешении IStorageCompetitorRepository дайте мне StorageCompetitorRepository».

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

Позже вы пытаетесь решить конкретную реализацию репозитория, и DI не может ее найти, так как она была зарегистрирована в контейнере только как интерфейс, имеет смысл? Измените это:

_storageCompetitorRepository = serviceProvider.GetService<StorageCompetitorRepository>();

К этому:

_storageCompetitorRepository = serviceProvider.GetService<IStorageCompetitorRepository>();

Если вы ХОТИТЕ иметь возможность разрешить конкретную реализацию, вам необходимо ее зарегистрировать.

AddTransient<StorageCompetitorRepository>();

Затем вы можете ТАКЖЕ зарегистрировать его как интерфейс, подобный этому, если вы хотите иметь возможность разрешать его и через интерфейс.

AddTransient<IStorageCompetitorRepository, StorageCompetitorRepository>();

Или

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

под ..AddTransient мне также пришлось сделать .AddDbContext

Steve020 12.05.2022 15:09

Другие вопросы по теме