.net - .net core 3:针对不同环境配置DI容器
问题描述
我正在将旧的 .net v 4.5.1 项目移植到最新的 .net 核心。对于旧的 .net 框架项目中的依赖注入,使用 Unity 容器,其中所有服务注册都存储在 web.config 中。
全球.asax:
UnityConfigurationSection section
= (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(container, "unityContainer");
网络配置:
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<container name="primaryUnityContainer">
<register type="ILogger" mapTo="Log4NetLogger"/>
问题是:.net core 3 在应用程序外部的配置文件中配置服务的最佳方式是什么,例如在 appsettings.json 中,以便可以为不同的环境注册不同的实现。
可以扩展内置容器还是使用具有此功能的某些 3rd 方更好?
为特定环境提供服务实现的其他方法是什么?
解决方案
您不能在应用程序之外的 ASP.NET Core 中配置服务。Microsoft.Extensions.DependencyInjection
完全基于代码,虽然您可以使用其他 DI 容器,但它们必须在Microsoft.Extensions.DependencyInjection
外观的框架内使用和配置。
也就是说,ASP.NET Core 中的“环境”是基于配置的。您不会为多个不同的环境多次编译应用程序。相反,您可以在启动时通过环境变量ASPNETCORE_ENVIRONMENT
(如通过 CLI 参数)或在运行时传递环境来指定环境。
无论哪种情况,您都可以根据环境值在代码中进行分支。实际上,您可以通过三种方式利用环境值来为每个环境配置不同的服务。
注入
IWebHostEnvironment
_Startup
private readonly IWebHostEnvironment _env; public Startup(IWebHostEnvironment env) { _env = env; }
然后,在
ConfigureServices
:if (_env.IsDevelopment()) { ... } if (_env.IsProduction()) { ... } if (_env.IsEnvironment("Foo")) { ... }
使用基于约定的命名与
ConfigureServices
. 换句话说,你可以Configure{EnvironmentName}Services
为你的类定义不同的方法Startup
:public void ConfigureDevelopmentServices(IServiceCollection services) { ... } public void ConfigureProductionServices(IServiceCollection services) { ... } public void ConfigureFooServices(IServiceCollection services) { ... }
Startup
对类本身使用基于约定的命名。您实际上可以定义多个Startup
类,如StartupDevelopment
,StartupProduction
,StartupFoo
等。一个问题是,UseStartup<T>
当您在Program.cs
. 相反,您需要 non-genericUseStartup
,它采用程序集名称字符串(因为您不知道在编译时实际需要什么启动类):public static IWebHostBuilder CreateWebHostBuilder(string[] args) { var assemblyName = typeof(Startup).GetTypeInfo().Assembly.FullName; return WebHost.CreateDefaultBuilder(args) .UseStartup(assemblyName); }
推荐阅读
- android - 为什么文本元素居中以及如何在 Dart 中将其与右侧对齐
- javascript - 给定注入的开始和结束索引,如何将 HTML 标记注入字符串?
- wordpress - Wordpress:从我的主题中的插件导入 scss
- python - 如何在 SQLAlchemy 数据库中正确定义图像并在数据库之间创建关系?
- nginx - nginx 和代理通道中的多个位置块
- c++ - 如何打印n之后的第b个素数?
- mysql - 联合所有字段,只给我一列
- javascript - 试图用 Intersection Observer 绘制谷歌图表
- c - 如何使用 18F4550 创建双向总线?
- r - 如何在同一张图上绘制这两个函数?