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

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

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

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

1、最基礎的應用Console

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

咱們來建立一個Console項目看一下:json

% dotnet new console -o demo

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

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

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

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

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

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

</Project>

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

注意,這個框架字串有個對照表: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應用。

2、轉爲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應用。

3、延伸內容

上面完成的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();
        });
    }
}

4、總結

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

但願對你們能有所幫助。

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

微信公衆號:老王Plus

掃描二維碼,關注我的公衆號,能夠第一時間獲得最新的我的文章和內容推送

本文版權歸做者全部,轉載請保留此聲明和原文連接

相關文章
相關標籤/搜索