深刻浅出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

扫描二维码,关注我的公众号,能够第一时间获得最新的我的文章和内容推送

本文版权归做者全部,转载请保留此声明和原文连接

相关文章
相关标签/搜索