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

时间:2018-11-08 08:48:42

标签: c# asp.net asp.net-core .net-core simple-injector

我遵循了本指南https://simpleinjector.org/aspnetcore来启动并运行基本应用。而且效果很好。

但是,我现在的需求有所不同。我的应用程序中的Web API基本上是一个可选端点,可能无法启动。但是,我想在整个应用程序中使用用于DI的Simple Injector。

在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核心相关的依赖树 prior 以执行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);
}

想要这个的原因是该应用程序不是以Http为中心的纯Web Api。它是一个遗留应用程序,其中包含许多后台线程来完成单独的工作,而并非所有这些线程都应以某种方式在网络api中公开。在某些环境中,甚至不应该启动Web API。您可能会争辩说应该以某种方式拆分应用程序,但是鉴于我的约束,这根本不是一个选择。

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

这有可能吗,我该怎么做?还是我以“错误的方式”使用这些工具?

1 个答案:

答案 0 :(得分:0)

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

基本上,该应用程序将变为:

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

这按我预期的那样工作。