.netcore基础知识(一)
Python微信訂餐小程序課程視頻
https://edu.csdn.net/course/detail/36074
Python實戰量化交易理財系統
https://edu.csdn.net/course/detail/35475
先來說說web服務器
先來一張圖 一個典型的進程外托管模型 我們先看kestrel這一部分 我們在它前面放了一個方向代理服務器nginx 對http請求做預處理 kestrel本身是可以直接用作web服務器的 但是其功能較弱 只有基礎功能 說白了就是一個弱化版的IIS 所以不建議直接將他暴露出來 一般會在前面加上一個反向代理服務器 當然圖中也可以將IIS作為反向代理服務器 但是這有點多此一舉了 我們可以直接用IIS 這時有IIS集成技術 會消耗更少資源 這時叫做進程內托管 所以其實一共就有兩種最優方案:
(1)確定要用IIS情況下 直接用IIS集成 進程內托管
(2)不確定要用IIS 建議Nginx/apache + Kestrel 這樣外部有一層反向代理 能有效做負載均衡,動靜分離,訪問控制,重定向等等 kestrel僅僅用來處理http請求
然后來講講Host主機
Program類就是用來創建主機的
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();});}看一下這段代碼 是不是很眼熟? Core的main方法就在這里 這是程序的入口 我們看一下他做了什么
CreateHostBuilder(args).Build().Run();上面這句就是:創建主機生成器 ----> 配置主機 ----> 創建主機 ----> 運行主機底下那個方法是前兩步 從 .Build().Run() 這兩步就是后面兩步主機有啥用? 微軟官方的說法是 ---- 主機負責應用程序啟動和生存期管理 說白了就是啟動程序和程序的生命周期的管理 主要用于配置服務器和請求處理管道。 主機還可以設置日志記錄、依賴關系注入和配置 就是一系列配置都是主機來做的
最后來講一下最重要的管道和中間件
public class Startup{public Startup(IConfiguration configuration){Configuration = configuration;}public IConfiguration Configuration { get; }// This method gets called by the runtime. Use this method to add services to the container.public void ConfigureServices(IServiceCollection services){services.AddControllers();}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapControllers();});}}看一下這段代碼 我們先看第一個方法?ConfigureServices 這個方法其實很多人都用過 它是用來配置IOC容器 因為Core最核心的點就在于我們要遵循依賴注入的原則 舉個例子 我們想要吃一個蘋果 我們要怎么做 當然是去商店買一個 而不是我們自己造一個?為啥呢?因為我們沒有造蘋果的圖紙啊 也就是說 我們想要造一個蘋果 首先我們需要一個造蘋果的圖紙 這樣其實我們就和蘋果類聯系在一起了 這個圖紙 在程序里就叫做構造方法 而例子里面的商店 其實就是IOC容器 我們想要蘋果就去商店買 我們不關心蘋果是怎么造出來的 都是商店來處理 我們就和蘋果解耦了 這就是非常典型的DI(依賴注入)思想 IOC容器其實就是反轉控制容器 幫我們造實例的容器 我們要的話直接找它拿就好了 我們就不用去 new() 對象了
話說回來?ConfigureServices 方法其實作用就是將我們這些“蘋果”進行注冊 說白了就是我們要給IOC容器提供構造方法吧 否則IOC容器也不知道怎么生產蘋果 那怎么注冊呢 請看下圖:
services.AddSingleton();services.AddTransient();services.AddScoped();可以看出來 后面兩個泛型參數第一個是實現類的接口 第二個是實現類 一共是三種方法進行注冊 我們要怎么區分這三種方法呢?
(1)AddSingleton() 這個表示單例 首次請求會創建這個服務實例 應用程序生命周期中從頭到尾只有這一個實例存在
(2)services.AddTransient() 這個表示瞬時 每次請求或用到這個實例 全部都是重新創建的
(3)services.AddScoped() 這個表示在同一個http請求中 或者說同一個線程中 這個實例只會被創建一次 舉個例子 A依賴B 請求進來了 A在方法里多次使用了B 那這個B的實例 都是同一個 加入下一次請求來了 那么就不是同一個了
多提一句 系統本來就注冊好的服務是已經設定好生命周期的 假如我們要自定義服務 我們要給它設定生命周期 注意 若同一個服務接口我們多次注冊 后面會覆蓋前面注冊的
我們再來看第二個方法Configure 這個方法其實就是用來構建管道 增加中間件的
IApplicationBuilder 其實就是一個管道構建器 我們看到下面的方法不斷在app.UseXXX() 其實這都是擴展方法 其實都是在添加中間件 http請求進來 所有的一切 都是中間件 不論是什么控制器 服務類 路由 身份驗證… 全部都是中間件 中間件之間的關系是怎么樣的 執行順序是怎么樣的 這是一個難點 首先說執行順序 實際上中間件是從第一個開始 執行到最后一個 然后從最后一個一直到第一個進行返回 中間件原則是:1.能將請求傳遞給下一個中間件 2.能夠進行響應,使管道短路? 短路是非常有必要的 沒有短路就沒有返回了 假如我們沒有設置在最后的短路中間件 系統會有一個報錯的最后中間件 強制短路返回
執行順序很有意思 先看我們自己寫的自定義中間件:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.Use(async (context, next) =>{await context.Response.WriteAsync("First Begin \r\n ");await next();await context.Response.WriteAsync("First End \r\n ");});app.Use(async (context, next) =>{await context.Response.WriteAsync("Second Begin \r\n ");await next();await context.Response.WriteAsync("Second End \r\n ");});app.UseRouting();app.UseEndpoints(endpoints =>{endpoints.MapGet("/", async context =>{await context.Response.WriteAsync("Hello World! \r\n");});});}可以看到我們寫了兩個自定義中間件 我們直接運行 看看他們執行順序是咋樣的:
是不是很有意思!我們現在就能理解了 next()實際上就是一個去找下一個中間件的委托 或者說next其實就是下一個中間件 先按照順序執行第一個中間件 然后next去找下一個中間件 第二個中間件的begin執行 然后執行next 找到下面的helloworld 這時候沒有下一個輸出了 這時候就返回了 從helloworld 到第二個中間件里面的代碼 就到了第二個的end 然后返回到第一個中間件 就到了第一個的end 就是這樣一個順序
而且我們也可以自己寫中間件 就像我圖上所示?app.Use() 方法 一共兩個參數
public static IApplicationBuilder Use(this IApplicationBuilder app, Func, Task> middleware){throw null;}第一個那個this是拓展方法用的 是一種方便用的簡寫 從第二個參數開始 我們看到實際上這個參數是一個委托 這個委托也有兩個參數 第一個是Http的上下文對象 第二個參數是一個Task型委托 其實就是我們的next 返回值也是一個Task 表明它指向的是一個異步方法
說白了 兩個參數其實就是?(context, next) 整體是異步的 所以前面要加 async 方法體里面調用的時候要用await? 因為next本身是異步方法
實際上在Core底層 next指向的就是下一個方法 委托其實就是一個函數指針 整體的處理是 先用一個List將所有中間件倒序放入 然后挨個取出 然后把反序第一個 也就是原先最后一個中間件當參數傳遞給前一個中間件的next 所以就能串起來 執行的時候第一個便可以根據next獲得下一個中間件 其實我們想一下 這不就是鏈表嗎 委托就是函數指針 鏈表里面的元素就是方法 不過都是用指針來處理的而已
最后還要提一點 要是我們寫自定義中間件 要用擴展方法 這是約定原則
總結
以上是生活随笔為你收集整理的.netcore基础知识(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 视频播放过程中做视频问答(视频弹题功能)
- 下一篇: 2020找工作更难了?做好这4方面,找到