iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0
Modern Web

擁抱 .Net Core系列 第 7

[Day7] asp.net core 中的Web主機(Host) - 2

  • 分享至 

  • xImage
  •  

asp.net core 3 與 5 的WebHost

.Net Core 3 跟5 的Host 主要定義在 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>(); });
}

可以注意到這邊不是透過new HostBuilder()的方式建立HostBuilder
而是透過靜態方法Host.CreateDefaultBuilder 來建立HostBuilder
這邊直接把說明打在註解了

Host.cs

public static IHostBuilder CreateDefaultBuilder(string[] args)
{
    // 你沒看錯,內部還是new了一個HostBuilder物件
    var builder = new HostBuilder();

    // 設定根目錄
    builder.UseContentRoot(Directory.GetCurrentDirectory());
    
    // 設定環境變數
    builder.ConfigureHostConfiguration(config =>
    {
        config.AddEnvironmentVariables(prefix: "DOTNET_");
        if (args != null)
        {
            config.AddCommandLine(args);
        }
    });

    // 設定app設定
    builder.ConfigureAppConfiguration((hostingContext, config) =>
    {
        IHostEnvironment env = hostingContext.HostingEnvironment;

        bool reloadOnChange = hostingContext.Configuration.GetValue("hostBuilder:reloadConfigOnChange", defaultValue: true);

        // 設定設定的來源來自 appsettings.json,後面提到config時會再介紹
        config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: reloadOnChange)
              .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: reloadOnChange);

        if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName))
        {
            var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
            if (appAssembly != null)
            {
                config.AddUserSecrets(appAssembly, optional: true);
            }
        }

        config.AddEnvironmentVariables();

        if (args != null)
        {
            config.AddCommandLine(args);
        }
    })
    
    // log 設定
    .ConfigureLogging((hostingContext, logging) =>
    {
        bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);

        // IMPORTANT: This needs to be added *before* configuration is loaded, this lets
        // the defaults be overridden by the configuration.
        if (isWindows)
        {
            // Default the EventLogLoggerProvider to warning or above
            logging.AddFilter<EventLogLoggerProvider>(level => level >= LogLevel.Warning);
        }

        logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
        logging.AddConsole();
        logging.AddDebug();
        logging.AddEventSourceLogger();

        if (isWindows)
        {
            // Add the EventLogLoggerProvider on windows machines
            logging.AddEventLog();
        }

        logging.Configure(options =>
        {
            options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                                | ActivityTrackingOptions.TraceId
                                                | ActivityTrackingOptions.ParentId;
        });

    })
    .UseDefaultServiceProvider((context, options) =>
    {
        bool isDevelopment = context.HostingEnvironment.IsDevelopment();
        options.ValidateScopes = isDevelopment;
        options.ValidateOnBuild = isDevelopment;
    });

    return builder;
}

至於ConfigureWebHostDefaults方法

ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });

內部主要做了幾件事,

  1. 建立一個HttpServer跟相關設定
  2. 設定承載的的相關服務與Middleware
  3. 定義了要承載的服務GenericWebHostService.cs source code
webBuilder.UseStartup<Startup>();

這行會去讀取Startup.cs中的ConfigureServices方法 並註冊到HostIServiceCollection
還有Configure 的自定義管線也會被定義到Host中

我們前面有提過,在啟動Host的時候,會依序呼叫所有註冊在HostIHostService 類別的StartAsync
GenericWebHostService.cs 本身實作了 IHostService
StartAsync的方法會去啟動 httpServer
server 會去監聽http請求 並依我們定義好的Pipline 執行回應

WebApplication

當我們建立一個asp.net core 6 的web 應用程式時
可以看見系統預設幫我們建立了範本中使用了WebApplication

WebApplicationBuilder builder = WebApplication.CreateBuilder(args)

內部其實也做了跟上面看見的CreateHostBuilder,差不多的事情(雖然有些差異,原諒我偷懶)

 public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });

但是可以看見的是,dotnet 6 少了Startup.cs 這個類別
所有Service的定義以及Config的設定都放到了Program.cs

DI Container 設定,使用AutoFac

var builder = WebApplication.CreateBuilder(args);
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

Config Source 設定

builder.Configuration.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

上一篇
[Day6] 泛型主機(Host) - 1
下一篇
[Day8] 檔案提供者(檔案系統)
系列文
擁抱 .Net Core30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言