IHostingEnvironment VS IHostEnvironment - .NET Core 3.0中的废弃类型

原文:https://andrewlock.net/ihostingenvironment-vs-ihost-environment-obsolete-types-in-net-core-3/

作者:Andrew Lock

译者:Lamond Lu

本篇是如何升级到ASP.NET Core 3.0系列文章的第二篇。

  • Part 1 - 将.NET Standard 2.0 类库转换为.NET Core 3.0 类库

  • Part 2 - IHostingEnvironment VS IHostEnvironment - .NET Core 3.0 中的废弃类型(本篇)[1]

  • Part 3 - 避免在 ASP.NET Core 3.0 启动时注入服务

  • Part 4 - 将终端中间件转换为 ASP.NET Core 3.0 中的节点路由

  • Part 5 - 将集成测试的转换为 NET Core 3.0

在本篇博客中,我将描述与之前版本相比,ASP.NET Core 3.0 中已经被标记为废弃的类型。我将解释一下为什么这些类型被废弃了,它们的替换类型是什么,以及你应该什么时候使用它们。


ASP.NET Core 与通用主机(Generic Host)合并

在 ASP.NET Core 2.1 中引入了新的通用主机(Generic Host), 它是借助Microsoft.Extension.*程序集来进行程序配置,依赖注入,以及日志记录来构建非 HTTP 应用的一种方式。虽然这是一个相当不错的点子,但是引入主机抽象在基础上与 ASP.NET Core 使用的 HTTP 主机不兼容。这导致了多种命名空间的冲突与不兼容,所以在 ASP.NET Core 2.x 版本中,我一直尽量不使用通用主机。

在 ASP.NET Core 3.0 中,开发人员作出了巨大的努力,将 Web 主机与通用主机兼容起来。ASP.NET Core 的 Web 主机现在可以作为IHostedService运行在通用主机中,重复抽象的问题(ASP.NET Core 中使用一套抽象,通用主机使用另一套抽象)得到了根本解决。

当然,这还不是全部。当你从 ASP.NET Core 2.x 升级到 3.0, ASP.NET Core 3.0 并不强迫你立即使用新的通用主机。如果你愿意,你可以继续使用旧的WebHostBuilder,而不使用新的HostBuilder。虽然在 ASP.NET Core 3.0 的官方文档[2]中一直暗示这是必须的,但是在当前的阶段,这是一个可选配置,如果你需要,可以继续使用 Web 主机,而不使用通用主机。

PS: 不过我还是建议你将可能将HostBuilder作为你未来的升级计划。我但是在未来的某个时间点WebHostBuilder将被移除,即使现在它还没有被标记为[Obsolete]

作为重构的通用主机的一部分,一些在之前版本中重复的类型被标记为废弃了,一些新的类型被引入了。在这些类型中,最好的例子就是IHostingEnvironment

IHostingEnvironment VS IHostEnvironment VS IWebHostEnviornment

IHostingEnvironment是.NET Core 2.x 中最让人讨厌的一个接口,因为它存在于两个命名空间中, Microsoft.AspNetCore.HostingMicrosoft.Extensions.Hosting.这两个接口有少许不同,且不兼容。

namespace Microsoft.AspNetCore.Hosting
{public interface IHostingEnvironment{string EnvironmentName { get; set; }string ApplicationName { get; set; }string WebRootPath { get; set; }IFileProvider WebRootFileProvider { get; set; }string ContentRootPath { get; set; }IFileProvider ContentRootFileProvider { get; set; }}
}namespace Microsoft.Extensions.Hosting
{public interface IHostingEnvironment{string EnvironmentName { get; set; }string ApplicationName { get; set; }string ContentRootPath { get; set; }IFileProvider ContentRootFileProvider { get; set; }}
}

之所以有两个同名接口是有历史原因的。AspNetCore版本的接口已经存在了很长时间了,在 ASP.NET Core 2.1 版本中,通用主机引入了Extensions版本。Extensions版本没有提供用于服务静态文件的wwwroot目录的概念(因为它承载的是非 HTTP 服务)。所以你可能已经注意到Extensions缺少了WebRootFileProviderWebRootPath两个属性。

出于向后兼容的原因,这里需要一个单独的抽象。但是,这种做法真正令人讨厌的后果之一是无法编写用于通用主机和 ASP.NET Core 的扩展方法。

在 ASP.NET Core 3.0 中,上述的两个接口都已经被标记为废弃了。你依然可以使用它们,但是在编译的时候,你会得到一些警告。相对的,两个新的接口被引入进来: IHostEnvironmentIWebHostEnvironment。虽然他们出现在不同的命名空间中,但是现在它们有了不同的名字,而且使用了继承关系。

namespace Microsoft.Extensions.Hosting
{public interface IHostEnvironment{string EnvironmentName { get; set; }string ApplicationName { get; set; }string ContentRootPath { get; set; }IFileProvider ContentRootFileProvider { get; set; }}
}namespace Microsoft.AspNetCore.Hosting
{public interface IWebHostEnvironment : IHostEnvironment{string WebRootPath { get; set; }IFileProvider WebRootFileProvider { get; set; }}
}

这个层次关系更容易理解了,避免了重复,并且意味着接收通用主机版本宿主环境抽象(IHostEnvironment)的方法现在也可以接收 web 版本(IWebHostEnvironment)的抽象了。在幕后,IHostEnvironmentIWebHostEnvironment的实现是相同的 - 除了旧接口,他们还实现了新接口。

例如,ASP.NET Core 的实现类如下:

namespace Microsoft.AspNetCore.Hosting
{internal class HostingEnvironment : IHostingEnvironment,Extensions.Hosting.IHostingEnvironment,IWebHostEnvironment{public string EnvironmentName { get; set; }= Extensions.Hosting.Environments.Production;public string ApplicationName { get; set; }public string WebRootPath { get; set; }public IFileProvider WebRootFileProvider { get; set; }public string ContentRootPath { get; set; }public IFileProvider ContentRootFileProvider { get; set; }}
}

那么你到底应该使用哪个接口呢?最简单的答案是"尽可能使用IHostEnvironment接口"。

但是详细来说,情况有很多。。。

如果你正在编写的 ASP.NET Core 3.0 的应用

尽可能是使用IHostEnviornment接口,但你需要访问WebRootPathWebRootFileProvider两个属性的时候,请使用IWebHostEnvironment接口。

如果你正在编写一个在通用主机和.NET Core 3.0 项目中使用的类库

使用IHostEnvironment接口。你的类库依然可以在 ASP.NET Core 3.0 应用中可用。

如果你正在编写一个在 ASP.NET Core 3.0 应用中使用的类库

和之前一样,尽量使用IHostEnvironment接口,因为你的类库可能不仅使用在 ASP.NET Core 应用中,还有可能使用在其他通用主机应用中。然而,如果你需要访问IWebHostEnvironment接口中的额外属性,那么你可能不得不更新你的类库,让它面向netcoreapp3.0,而不是netstandard2.0, 并且添加<FreameworkReference>元素配置。

如果你正在编写一个在 ASP.NET Core 2.x 和 3.0 中使用的类库

这种场景比较难处理,基本上你有两种可选的方案:

  • 你可以继续使用Microsoft.AspNetCore版本的IHostingEnvironment。它在 2.x 和 3.0 应用中都可以正常工作,你只需要在后续版本中停止使用即可。

  • 使用#ifdef条件编译指令,针对 ASP.NET Core 3.0 使用IHostEnvironment接口,针对 ASP.NET Core 2.x 使用IHostingEnviornment接口。

IApplicationLifetime VS IHostApplicationLifetime

IHostingEnvironment接口相似,IApplicationLifetime接口也有命名空间的冲突问题。和之前的例子相同,这两个接口分别存在于Microsoft.Extensions.HostingMicrosoft.AspNetCore.Hosting中。但是在这个例子中,这两个接口是完全一致的。

// 与Microsoft.AspNetCore.Hosting中的定义完全一致
namespace Microsoft.Extensions.Hosting
{public interface IApplicationLifetime{CancellationToken ApplicationStarted { get; }CancellationToken ApplicationStopped { get; }CancellationToken ApplicationStopping { get; }void StopApplication();}
}

如你所料,这种重复是向后兼容的征兆。在.NET Core 3.0 中新的接口IHostApplicationLifetime被引入,该接口仅在Microsoft.Extensions.Hosting命名空间中定义,但是在通用主机和 ASP.NET Core 应用中都可以使用。

namespace Microsoft.Extensions.Hosting
{public interface IHostApplicationLifetime{CancellationToken ApplicationStarted { get; }CancellationToken ApplicationStopping { get; }CancellationToken ApplicationStopped { get; }void StopApplication();}
}

同样的,这个接口和之前版本是完全一致的。ApplicationLifetime类型在通用主机项目的启动和关闭中扮演了非常重要的角色。非常有趣的是,在Microsoft.AspNetCore.Hosting中没有一个真正等价的类型,Extensions版本的接口处理了两种不同的实现。AspNetCore命名空间中唯一的实现是一个简单的封装类,类型将实现委托给了一个作为通用主机部分被添加的ApplicationLifetime对象中。

namespace Microsoft.AspNetCore.Hosting
{internal class GenericWebHostApplicationLifetime : IApplicationLifetime{private readonly IHostApplicationLifetime _applicationLifetime;public GenericWebHostApplicationLifetime(IHostApplicationLifetime applicationLifetime){_applicationLifetime = applicationLifetime;}public CancellationToken ApplicationStarted =>_applicationLifetime.ApplicationStarted;public CancellationToken ApplicationStopping =>_applicationLifetime.ApplicationStopping;public CancellationToken ApplicationStopped =>_applicationLifetime.ApplicationStopped;public void StopApplication() =>_applicationLifetime.StopApplication();}
}

幸运的是,选择使用哪一个接口,比选择托管环境(Hosting Environment)要简单的多。

如果你正在编写一个.NET Core 3.0 或者 ASP.NET Core 3.0 应用或者类库

使用IHostApplicationLifetime接口。你只需要引用Microsoft.Extensions.Hosting.Abstractions, 即可以在所有应用中使用。

如果你在编写一个被 ASP.NET Core 2.x 和 3.0 应用共同使用的类库

现在,你可能又会陷入困境:

  • 你可以继续使用Microsoft.Extensions版本的IApplicationLifetime。它在 2.x 和 3.0 应用中都可以正常使用,但是在未来的版本中,你将不得不停止使用它

  • 使用#ifdef条件编译指令,针对 ASP.NET Core 3.0 使用IHostApplicationLifetime接口,针对 ASP.NET Core 2.x 使用IApplicationLifetime接口。

幸运的是,IApplicationLifetime接口通常使用的比IHostingEnvironment接口少的多,所以你可能不会在此遇到过多的困难。

IWebHost VS IHost

这里有一件事情可能让你惊讶,IWebHost接口没有被更新,它没有继承 ASP.NET Core 3.0 中的IHost。相似的,IWebHostBuilder也没有继承自IHostBuilder。它们依然是完全独立的接口, 一个只工作在 ASP.NET Core 中,一个只工作在通用主机中。

幸运的是,这也没有关系。现在 ASP.NET Core 3.0 已经被重构使用通用主机的抽象接口, 你可以编写使用通用主机IHostBuilder抽象的方法,并在 ASP.NET Core 和通用主机应用中共享它们。如果你需要进行 ASP.NET Core 的特定操作,你可以依然使用IWebHostBuilder接口。

例如,你可以编写如下的扩展方法,一个使用IHostBuilder, 一个使用IWebHostBuilder:

public static class ExampleExtensions
{public static IHostBuilder DoSomethingGeneric(this IHostBuilder builder){// 添加通用主机配置return builder;}public static IWebHostBuilder DoSomethingWeb(this IWebHostBuilder builder){// 添加Web托管配置return builder;}
}

其中一个方法在通用主机上进行某些配置(列入,使用依赖注入注册某些服务),在另外一个方法中对IWebHostBuilder进行某种配置,例如你可能会为 Kestrel 服务器设置一些默认值。

如果你在创建了一个全新的 ASP.NET Core 3.0 应用,你的Program.cs文件看起来应该是如下代码:

public class Program
{public static void Main(string[] args) => CreateHostBuilder(args).Build().Run();public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});
}

你可以添加针对两个扩展方法的调用。一个在通用IHostBuilder上调用,另一个在ConfigWebHostDefaults()方法中,针对IWebHostBuilder调用

public class Program
{public static void Main(string[] args) => CreateHostBuilder(args).Build().Run();public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).DoSomethingGeneric() // IHostBuilder扩展方法.ConfigureWebHostDefaults(webBuilder =>{webBuilder.DoSomethingWeb() // IWebHostBuilder扩展方法.UseStartup<Startup>();});
}

在 ASP.NET Core 3.0 中,你可以对两种构建器类型进行调用,这意味着,你现在可以仅依赖通用主机的抽象,就可以在 ASP.NET Core 应用中复用它们。然后,你可以将 ASP.NET Core 的特性行为放在顶层,而不必像 2.x 中一样重复方法。

总结

在本文中,我们讨论了 ASP.NET Core 3.0 中一些被标记为废弃的类型,它们被移动到哪里去了,以及这么做的原因。如果你正在将一个应用升级到 ASP.NET Core 3.0, 你并不需要马上替换它们,因为他们现在的行为依然相同,但是在将来的版本中会被替换掉,因此如果可以的话,最好对其进行更新。在某些场景中,它还使你的应用之间共享代码更加容易,因此值得研究一下。

参考资料

[1]

IHostingEnvironment VS IHostEnvironment - .NET Core 3.0中的废弃类型(本篇): https://www.cnblogs.com/lwqlun/p/12153935.html

[2]

官方文档: https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312380.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【敏捷案例】老板太外行,朝令夕改!要不要拿了年终奖就撤?

快到春节了&#xff0c;不知道有多少人在等着春节后跳槽&#xff0c;想跳槽的原因也很多&#xff0c;其中一个比较普遍的原因是和老板聊不到一块儿去。前两天&#xff0c;有个学员咨询了我们一个问题&#xff0c;因为这个问题比较普遍&#xff0c;拿出来和大家一起讨论一下~提出…

【2019总结篇】谈谈数字化时代,ERP如何坐稳数字化底座

源宝导读&#xff1a;面向未来&#xff0c;信息化、在线化、智能化&#xff0c;开放应该是数字化转型的核心要素&#xff01;本文将重点介绍2019年明源云ERP开放平台在推进数字化转型中的核心技术层面的实践成果。一、前言面向未来&#xff0c;信息化、在线化、智能化&#xff…

dotNetCore操作Redis(含CentOS7哨兵模式部署)

现在说到使用缓存中间件基本就是 Redis 了&#xff0c;通常开发环境或测试环境部署一个单机版就可以运行了&#xff0c;但要上生产环境还需要进行高可用的方式来部署&#xff0c;本文说说在 CentOS7 中 Redis 高可用的部署以及在 dotNetCore 中怎样调用。环境CentOS&#xff1a…

php和mysql一键安装包_iis+php+mysql一键安装教程和安装包

导读&#xff1a;iis上mysqlphp一键安装 很多用vps的朋友&#xff0c;在windons系统iis上配置mysqlphp环境的时候都非常的头痛&#xff0c;过程非常复杂和麻烦&#xff0c;所以我们推荐大家用mysqlphp一键安装包&#xff1a; 1、下载mysqlphp一键安装包&#xff0c;安装包下载地…

程序员过关斩将--自定义线程池来实现文档转码

背景我司在很久之前&#xff0c;一位很久之前的同事写过一个文档转图片的服务&#xff0c;具体业务如下&#xff1a;1. 用户在客户端上传文档&#xff0c;可以是ppt&#xff0c;word&#xff0c;pdf 等格式&#xff0c;用户上传完成可以在客户端预览上传的文档&#xff0c;预览…

UnitTest in .NET(Part 4)

Photo &#xff1a;Unit Test in Visual Studio文 | Edison Zhou上一篇我们学习了如何使用模拟对象进行交互测试。这一篇我们则会进一步使用隔离框架支持适应未来和可用性的功能。为何使用模拟框架&#xff1f; 对于复杂的交互场景&#xff0c;可能手工编写模拟对象和存根就会变…

Xamarin.Forms弹出对话框插件

微信公众号&#xff1a;Dotnet9&#xff0c;网站&#xff1a;Dotnet9&#xff0c;问题或建议&#xff0c;请网站留言&#xff1b;如果您觉得Dotnet9对您有帮助&#xff0c;欢迎赞赏。Dotnet9.com内容目录实现效果业务场景编码实现本文参考源码下载1.实现效果弹出动画 2.业务场景…

Pycharm安装第三方库

转载地址&#xff1a; https://www.cnblogs.com/bwjblogs/p/12839463.html 今晚想安装一些第三方库但是pip版本低&#xff0c;安装一直报错&#xff0c;输入升级的命令也一直不行。于是在pycharm上安装&#xff0c;但是还是一直失败&#xff0c;下面提出解决办法。 然后在搜索…

CAP 3.0 版本正式发布

前言大家好&#xff0c;我们很高兴宣布 CAP 发布了 3.0 版本正式版。自从上次 CAP 2.6 版本发布 以来&#xff0c;已经过去了几个月的时间&#xff0c;关注的朋友可能知道&#xff0c;在这几个月的时间里&#xff0c;也发布了几个预览版的 3.0 版本的NuGet包。3.0 是一个主要版…

mysql字符集变为gbk_MYSQL数据库默认latin1字符集转换为GBK或UTF8

可以采用下面的方法latin1字符集转换为gbk字符集或utf8字符集。具体的转换步骤如下&#xff1a;一、latin1转gbk1、导出数据库mysqldump --default-character-setlatin1 -h 数据库连接ip -u root -P 3306 -p数据库密码 db_name table_name > /usr/home/test/table_name.sql2…

微服务统计,分析,图表,监控一体化的HttpReports项目在.Net Core 中的使用

简单介绍HttpReports 是 .Net Core 下的一个Web项目, 适用于WebAPI&#xff0c;Ocelot网关应用&#xff0c;MVC项目&#xff0c;非常适合针对微服务应用使用&#xff0c;通过中间件的形式集成到您的项目中&#xff0c;可以让开发人员快速的搭建出一个 数据统计&#xff0c;分析…

查看node的位置_升级Node版本RN项目运行报错cb.apply is not a function

今日打算安装一下ReactNative官方推荐的脚手架工具Ignite。infinitered/ignite​github.comIgnite是一套整合了 Redux 以及一些常见 UI 组件的脚手架。它带有一个命令行可以生成 app、组件或是容器。在安装的过程中&#xff0c;提示当前系统安装的node版本过低&#xff0c;无法…

C++构造函数调用规则

1.拷贝函数的值拷贝&#xff1a; #include <iostream> using namespace std;//构造函数的调用规则&#xff1a; //1,创建一个类&#xff0c;C编译器会给每个类都添加至少3个函数 //默认函数(空实现)&#xff0c;析构函数(空实现)&#xff0c;拷贝函数(值拷贝)class Pers…

HTTP Strict Transport Security (HSTS) in ASP.NET Core

本文是《2020年了&#xff0c;再不会HTTPS就老了》的后篇&#xff0c;本文着重聊一聊HTTP Strict Transport Security协议的概念和应用。启用 HTTPS 还不够安全现在很多站点通过HTTPS对外提供服务&#xff0c;用户在访问某站点&#xff0c;往往会直接输入站点域名&#xff08;b…

mysql支持的平台和操作系统_MySQL 数据库所支持的操作系统_MySQL

MySQL数据库所支持的操作系统&#xff1a;我们使用GNU Autoconf&#xff0c;因此将MySQL移植到所有使用Posix线程和C编译器的现代系统是可能的。(要求服务器支持线程。如果只是编译客户端代码&#xff0c;则只需要C编译器)。我们主要在Linux(SuSE和Red Hat)、FreeBSD和Sun Sola…

C++深拷贝与浅拷贝

浅拷贝&#xff1a; 简单的赋值拷贝操作。 深拷贝&#xff1a; 在堆区重新申请空间&#xff0c;进行拷贝操作。 首先我们先写这样的一段代码&#xff1a; #include <iostream> using namespace std; //深拷贝与浅拷贝class Person {public:Person() {cout << &qu…

BeetleX轻松搭建HTTP和Weboskcet网关

在新版本的BeetleX.Bumblebee中实现了对Weboskcet代理的支持&#xff0c;因此使用BeetleX搭建同时支持HTTP和Weboskcet的网关只需要几行代码的工作就能完成&#xff1b;接下来构建一个简单的网关程序并测试一下对asp.net core SignalR进行代理的应用。引用组件使用BeetleX构建网…

[功能发布]Excel与PowerBI互通互联升级版连接SSAS和AzureAS

Excel催化剂发自内心地热爱着PowerBI社区&#xff0c;从最开始提供了PowerBIDeskTop的互通互联功能&#xff0c;到无偿奉献所有此功能的核心原代码&#xff0c;再到今天的高潮&#xff0c;献上最具商业价值的高级功能&#xff0c;让企业级商业智能BI项目插上翅膀&#xff0c;最…

window oracle 只有bak文件怎么恢复_一起来学习Oracle的备份恢复基础吧-4

基于backup controlfile的恢复使用备份的控制文件在实际工作中的两种情况&#xff1a;当前控制文件全部损坏&#xff0c;而数据文件备份、控制文件备份及当前的日志处在不同的SCN版本&#xff0c;它们之间又增加过表空间(数据文件)。当前控制文件没有损坏&#xff0c;但是想恢复…

微服务、容器和Kubernetes的2020你怎么看?

历史上&#xff0c;有些年份比其他年份容易预测。因为市场出现的稳定性使追踪趋势线变得更加容易。2020年将是企业向微服务迁移的关键一年&#xff1a;稳定并逐步地向主流应用过渡。毫无疑问&#xff0c;IT组织正在转向微服务架构。微服务将应用程序分解为许多小部分&#xff0…