将 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);
}
这符合我的预期。
我按照本指南 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);
}
这符合我的预期。