IHostingEnvironmentVSIHostEnvironment-.NETCor。。。

透明国际组织
IHostingEnvironmentVSIHostEnvironment-.NETCor。。。
本篇是如何升级到ASP.NET Core 3.0系列⽂章的第⼆篇。
Part 1 - 将.NET Standard 2.0类库转换为.NET Core 3.0类库
Part 2 - IHostingEnvironment VS IHostEnvironment - .NET Core 3.0中的废弃类型(本篇)
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的官⽅⽂档中⼀直暗⽰这是必须的,但是在当前的阶段,这是⼀个可选配置,如果你需要,可以继续使⽤Web主机,⽽不使⽤通⽤主机。
PS: 不过我还是建议你将可能将HostBuilder作为你未来的升级计划。我但是在未来的某个时间点WebHostBuilder将被移除,即使现在它还没有被标记为[Obsolete]。
作为重构的通⽤主机的⼀部分,⼀些在之前版本中重复的类型被标记为废弃了,⼀些新的类型被引⼊了。在这些类型中,最好的例⼦就
是IHostingEnvironment。
IHostingEnvironment VS IHostEnvironment VS IWebHostEnviornment
IHostingEnvironment是.NET Core 2.x中最让⼈讨厌的⼀个接⼝,因为它存在于两个命名空间中,
Microsoft.AspNetCore.Hosting和Microsoft.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缺少了WebRootFileProvider和WebRootPath两个属性。
出于向后兼容的原因,这⾥需要⼀个单独的抽象。但是,这种做法真正令⼈讨厌的后果之⼀是⽆法编写⽤于通⽤主机和ASP.NET Core的扩展⽅法。
在ASP.NET Core 3.0中,上述的两个接⼝都已经被标记为废弃了。你依然可以使⽤它们,但是在编译的时候,你会得到⼀些警告。相对的,两个新的接⼝被引⼊进来: IHostEnvironment和IWebHostEnvironment。虽然他们出现在不同的命名空间中,但是现在它们有了不同的名字,⽽且使⽤了继承关系。
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)的抽象了。在幕后,IHostEnvironment和IWebHostEnvironment的实现是相同的 - 除了旧接⼝,他们还实现了新接⼝。
例如,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接⼝,但你需要访问WebRootPath和WebRootFileProvider两个属性的时候,请使⽤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.Hosting和Microsoft.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, 你并不需要马上替换它们,因为他们现在的⾏为依然相同,但是在将来的版本中会被替换掉,因此如果可以的话,最好对其进⾏更新。在某些场景中,它还使你的应⽤之间共享代码更加容易,因此值得研究⼀下。
避免在ASP.NET Core 3.0中为启动类注⼊服务
本篇是如何升级到ASP.NET Core 3.0系列⽂章的第⼆篇。
Part 1 - 将.NET Standard 2.0类库转换为.NET Core 3.0类库
Part 2 - IHostingEnvironment VS IHostEnvironent - .NET Core 3.0中的废弃类型
Part 3 - 避免在ASP.NET Core 3.0中为启动类注⼊服务(本篇)
Part 4 - 将终端中间件转换为ASP.NET Core 3.0中的端点路由
Part 5 - 将集成测试的转换为NET Core 3.0
在本篇博客中,我将描述从ASP.NET Core 2.x应⽤升级到.NET Core 3.0需要做的⼀个修改:你不在需要在Startup构造函数中注⼊服务了。
在ASP.NET Core 3.0中迁移到通⽤主机
在.NET Core 3.0中, ASP.NET Core 3.0的托管基础已经被重新设计为通⽤主机,⽽不再与之并⾏使⽤。那么这对于那些正在使⽤ASP.NET Core 2.x开发应⽤的开发⼈员,这意味着什么呢?在⽬前这个
阶段,我已经迁移了多个应⽤,到⽬前为⽌,⼀切都进展顺利。官⽅的迁移指导⽂档可以很好的指导你完成所需的步骤,因此,我强烈建议你读⼀下这篇⽂档。

本文发布于:2024-09-23 21:25:35,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/160835.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:可能   版本   类型   配置   命名   空间   转换   服务
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议