深入淺出Dotnet Core的項目結構變化

有時候,越是基礎的東西,越是有人不明白。

前幾天Review一個項目的代碼,發現非常基礎的內容,也會有人理解出錯。

今天,就着這個點,寫一下Dotnet Core的主要類型的項目結構,以及之間的轉換和演化。

一、最基礎的應用Console

控制檯應用,是Dotnet Core乃至前邊的Dotnet Framework中,最基礎的項目。

我們來創建一個Console項目看一下:

% dotnet new console -o demo

創建完成後,打開工程。工程裏只有一個文件Program.cs,裏面只有一個方法Main

namespace demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

在Dotnet Core所有類型的項目中,Program.cs都是最開始的入口,main方法,也是最開始的入口方法。

這個工程中,還有一個文件也需要了解一下,demo.csproj,這是這個項目的定義文件:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

</Project>

這裏面,OutputType告訴編輯器這個工程編譯後可以直接執行,TargetFramework定義運行的框架。

注意,這個框架字串有個對照表:net5.0對應的是.Net 5.0;如果你想用Dotnet Core 3.1,對應的字符串是netcoreapp3.1,而不是net3.1。準確的說,3.1是.Net Core 3.1,而5.0是.Net 5.0。不用太糾結,微軟的命名規則而已。

    爲了防止不提供原網址的轉載,特在這裏加上原文鏈接:https://www.cnblogs.com/tiger-wang/p/14267942.html

這就是控制檯應用Console的初始狀態。

下面,我們看看這個工程如何轉變爲Web應用。

二、轉爲Web應用

第一件事,我們需要改動demo.csproj項目定義文件。

Web應用跑在WebHost上面,而不是從直接執行。所以,我們需要把OutputType項去掉。

另外,SDK也需要改一下。Console我們用的是Microsoft.NET.Sdk,Web應用要改成Microsoft.NET.Sdk.Web

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

</Project>

改完保存。

這時候,應該可以注意到,項目的發生了變化:

  • 依賴的框架從Microsoft.NETCore.App變成了兩個,多了一個Microsoft.AspNetCore.App,表明現在這是一個Asp.net Core的應用;
  • 項目中自動生成了一個目錄Properties,下面多了一個文件launchSettings.json。這個文件大家應該很熟悉,就不解釋了。

這時候,應用已經從Console轉爲了Web應用。

Asp.Net Core框架提供了Host供Web加載。我們需要做的,是把Host構建器加到程序中。通常,我們需要兩個構建器:

  • 通用主機 Generic host builder
  • Web主機 Web host builder

1. 配置通用主機

通用主機在Microsoft.Extensions.Hosting.Host中,主要給Web應用提供以下功能:

  • 依賴注入
  • 日誌
  • 配置 IConfiguration
  • IHostedService實現

加入通用主機很簡單,就一個方法CreateDefaultBuilder

class Program
{
    static void Main(string[] args)
    {
        Host.CreateDefaultBuilder(args)
            .Build()
            .Run();
    }
}

2. 配置Web主機

Web主機纔是真正與Web相關的內容,主要實現:

  • Http支持
  • 設置Kestrol服務器爲Web服務器
  • 添加IIS支持

加入Web主機,也是一個方法ConfigureWebHostDefaults

class Program
{
    static void Main(string[] args)
    {
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
            })
            .Build()
            .Run();
    }
}

這個方法用來添加Http請求管道並注入我們需要的服務。而注入我們需要的服務,就是我們最常見的Startup.cs的內容。

下面,我們先創建Startup.cs

namespace demo
{
    public class Startup
    {
    }
}

在前邊ConfigureWebHostDefaults中,加入Startup,並補齊代碼:

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

這就是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>();
            });
}

不過,到這兒還不能正常運行,因爲Startup.cs現在還是空的。

3. 補齊Startup類

Startup類在Asp.net Core應用中有着重要的作用。這個類用於:

  • 使用DI容器注入服務
  • 設置Http Request管道以插入中間件

下面我們補齊所需的方法:

namespace demo
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
        }
    }
}

運行,到這兒,Web應用已經可以正常啓動了。

4. 給應用添加路由

Web應用啓動了,但裏面什麼也沒有,是空的。

要訪問Web應用中的任何資源,需要配置路由。這兒的路由,基本上就是傳入Http請求與資源之間的映射。

我們可以用下面的中間件來啓動路由:

  • UseRouting
  • UseEndpoints

加一下試試:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseRouting();
    app.UseEndpoints(endpoint => {
        endpoint.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello from Demo");
        });
    });
}

這次運行,瀏覽器中就看到正確的輸出了。

我們可以用MapGet映射更多資源:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseRouting();
    app.UseEndpoints(endpoint =>
    {
        endpoint.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello from Demo");
        });
        endpoint.MapGet("/test", async context =>
        {
            await context.Response.WriteAsync("Hello from Demo.Test");
        });
        endpoint.MapGet("/about", async context =>
        {
            await context.Response.WriteAsync("Hello from Demo.About");
        });
    });
}

到這兒,我們成功地把Console應用轉爲了Web應用。

三、延伸內容

上面完成的Web應用,算是Web應用中的基礎。基於這個內容,我們還可以擴展到別的項目結構。

1. 改爲MVC應用

需要在ConfigureServices 中注入AddControllersWithViews,並在Configure中添加MapDefaultControllerRoute

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
    }
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseRouting();
        app.UseEndpoints(endpoint =>
        {
            endpoint.MapDefaultControllerRoute();
        });
    }
}

2. 改爲WebAPI應用

需要注入AddControllersMapControllers

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
    }
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseRouting();
        app.UseEndpoints(endpoint =>
        {
            endpoint.MapControllers();
        });
    }
}

3. 改爲Razor應用

需要注入AddRazorPagesMapRazorPages

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseRouting();
        app.UseEndpoints(endpoint =>
        {
            endpoint.MapRazorPages();
        });
    }
}

四、總結

看下來,其實過程很簡單。通過這種方式,能更進一步理解Dotnet Core的項目結構以及應用的運行過程。

希望對大家能有所幫助。

本文的配套代碼在:https://github.com/humornif/Demo-Code/tree/master/0038/demo

微信公衆號:老王Plus

掃描二維碼,關注個人公衆號,可以第一時間得到最新的個人文章和內容推送

本文版權歸作者所有,轉載請保留此聲明和原文鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章