将 Simple Injector 与可选 ASP.NET Core Web API 集成

Integrate Simple Injector with optional ASP.NET Core Web API

我按照本指南 https://simpleinjector.org/aspnetcore 启动了基本应用程序并 运行。而且效果很好。

不过,我现在的需求有点不同。我的应用程序中的 Web API 基本上是一个可能无法启动的可选端点。但是,我想在整个应用程序中使用用于 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();

StartUp 内部是我链接的相同代码。

我的问题是 SimpleInjector 容器保留(和设置)在 StartUp 中,我无法访问它。我真正想要的是设置所有非 aspnet 核心相关的依赖树 之前执行启动例程并与 aspnet 核心集成。

也就是下面摘录中的"add application services"部分:

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

想要这个的原因是这个应用程序不是一个以 Http 为中心的纯 Web Api。它是一个遗留应用程序,包含许多独立工作的后台线程,并非所有这些线程都应该以某种方式暴露在网络中 api。在某些环境中,网络 api 甚至不应该启动。您可能会争辩说应用程序应该以某种方式拆分,但考虑到我的限制,这根本不是一个选项。

简而言之:它解决了我想要在整个应用程序中使用相同的 DI 容器、依赖相同的服务、持久性访问等的目标,我的 REST 资源能够利用遗留应用程序的一部分功能。

这可能吗,我该如何实现?或者我在使用这些工具 "the wrong way"?

任何感兴趣的人。我做了史蒂文建议的解决方案。非常感谢。

基本上应用程序变成:

            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();

在 aspnetcore StartUp 类型中创建另一个容器实例并设置为:

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

这符合我的预期。