Nano Hash - криптовалюты, майнинг, программирование

Интеграция Simple Injector с дополнительным веб-API ASP.NET Core

Я следовал этому руководству https://simpleinjector.org/aspnetcore, чтобы настроить и запустить базовое приложение. И это прекрасно работает.

Однако сейчас мои потребности немного другие. Веб-API в моем приложении — это, по сути, необязательная конечная точка, которую нельзя запустить. Однако я хочу использовать Simple Injector для DI во всем приложении.

В моем Program.cs у меня есть следующие строки:

// REST API
if (Config.ReadSettingBool("StartRestEndpoint", false))
{
    LogManager.Info("Starting REST Endpoint...");
    try
    {
        _httpHost = new HttpHost(
            Config.ReadSetting("HttpHost", "localhost"),
            Config.ReadSetting("HttpPort", 8081),
            Config.ReadSetting("RestEnvironment", "Development"));
        _httpHost.Start();
        LogManager.Info("REST Endpoint started");
    }
    catch (Exception e)
    {
        LogManager.Error($"Failed to start REST endpoint: {e}");
    }
}

Теперь внутри HttpHost происходит следующее:

_webHost = WebHost.CreateDefaultBuilder()
    .UseUrls()
    .UseUrls(_url)
    .UseStartup<Startup>()
    .UseEnvironment(_environment)
    .Build();
_webHost.Start();

а внутри автозапуска тот же код, который я связал.

Моя проблема в том, что контейнер SimpleInjector хранится (и настраивается) внутри StartUp, и у меня нет возможности добраться до него. Что я действительно хочу, так это настроить все дерево зависимостей, не связанное с ядром aspnet, до выполнения процедуры StartUp и интеграции с ядром aspnet.

То есть часть «добавить прикладные службы» в приведенном ниже отрывке:

private void InitializeContainer(IApplicationBuilder app) {
    // Add application presentation components:
    container.RegisterMvcControllers(app);
    container.RegisterMvcViewComponents(app);

    // Add application services. For instance:
    container.Register<IUserService, UserService>(Lifestyle.Scoped);

    // Allow Simple Injector to resolve services from ASP.NET Core.
    container.AutoCrossWireAspNetComponents(app);
}

Причина этого в том, что это приложение не является чистым веб-API, сосредоточенным вокруг Http. Это устаревшее приложение, содержащее множество фоновых потоков, выполняющих отдельную работу, не все из которых должны каким-то образом отображаться в веб-API. В некоторых средах веб-API даже не следует запускать. Вы можете возразить, что приложение должно быть каким-то образом разделено, но, учитывая ограничения, которые у меня есть, это просто не вариант.

Вкратце: это решает мою цель — использовать один и тот же DI-контейнер, полагаться на одни и те же сервисы, постоянный доступ и многое другое во всем приложении, при этом мои ресурсы REST могут использовать части функциональности устаревшего приложения.

Возможно ли это, и как я могу это сделать? Или я использую эти инструменты «не так»?


  • Что я действительно хочу, так это настроить все дерево зависимостей, не связанное с ядром aspnet, до выполнения StartUp. Какую проблему это решает? Зачем тебе это? 08.11.2018
  • Попытался ответить на это более подробно в моем редактировании. 08.11.2018
  • Итак, почему бы не иметь 2 отдельных экземпляра контейнера? Должно ли приложение работать как таковое с одним единственным экземпляром Container? Было бы нормально, если бы веб-API получил свой собственный контейнер, изолированный от кода, работающего в фоновых потоках? 08.11.2018
  • Я думаю, это должно работать... Единственным недостатком будет дублирование кода для общих частей, но я могу с этим смириться. Можете ли вы прокомментировать, как я должен думать о синглтонах? Будет ли идея заключаться в том, чтобы они были как синглтоны на контейнер? Это единственная сложная проблема, о которой я могу думать. Честно говоря, я не рассматривал установку отдельного контейнера. Если я это сделаю, есть ли что-то еще, что я должен был бы рассмотреть? Если вы хотите написать ответ в том же духе, я был бы рад принять его. 08.11.2018
  • дублирование кода для частей, которые являются общими. С чего бы это? Почему нельзя использовать один и тот же метод Bootstrap(Container container), который вызывается как внутри Startup, так и из места, где настроено фоновое приложение? 08.11.2018
  • Компонент, зарегистрированный как Singleton, будет иметь только один экземпляр на экземпляр контейнера. В большинстве случаев это не должно быть проблемой, тем более что вы уже заявили, что приложение должно быть каким-то образом разделено, что по своей сути будет означать несколько доменов приложений и, следовательно, несколько экземпляров. Для тех немногих регистраций, где это на самом деле является проблемой, создайте их самостоятельно один раз и передайте их в контейнер с помощью RegisterInstance. 08.11.2018
  • Почему вы не можете использовать тот же Bootstrap (контейнер-контейнер). Как статический метод, который просто отвечает за объявление дерева зависимостей и вызывается из обоих мест? Похоже, это должно сработать. Извините за некоторые из этих вопросов, я признаю, что новичок в использовании этих инструментов. Я попробую это предложение и посмотрю, работает ли оно так, как ожидалось. 08.11.2018

Ответы:


1

Для всех, кто заинтересован. Я сделал решение, предложенное Стивеном. Большое тебе спасибо.

В основном приложение становится:

            LogManager.Info("Starting REST Endpoint...");
            try
            {
                _httpHost = new HttpHost(
                    Config.ReadSetting("HttpHost", "localhost"),
                    Config.ReadSetting("HttpPort", 8081),
                    Config.ReadSetting("RestEnvironment", "Development"));
                _httpHost.Start();
                LogManager.Info("REST Endpoint started");
            }
            catch (Exception e)
            {
                LogManager.Error($"Failed to start REST endpoint: {e}");
            }


            LogManager.Info("Starting Monitors...");
            // Set up dependency tree.
            Container _container = new Container();
            BootstrapDependencyInjectionTree.Bootstrap(_container);
            _container.Verify();

            _monitors = new Monitors(_container.GetInstance<IMonitorDefinitionRepository>());
            _monitors.RegisterMonitors();
            _monitors.StartContinuousMonitors();

с другим экземпляром контейнера, созданным внутри типа StartUp aspnetcore и настроенным как:

    private void InitializeContainer(IApplicationBuilder app)
    {
        // Add application presentation components:
        _container.RegisterMvcControllers(app);
        _container.RegisterMvcViewComponents(app);

        // Add application services.
        // This creates an object dependency graph that is used to populate all constructor arguments using DI.
        BootstrapDependencyInjectionTree.Bootstrap(_container);

        // Web api only dependencies.
        _container.RegisterSingleton<IMonitorMetaDataProvider, MonitorMetaDataProvider>();

        // Allow Simple Injector to resolve services from ASP.NET Core.
        _container.AutoCrossWireAspNetComponents(app);
    }

Это работает, как я и ожидал.

08.11.2018
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..