zoukankan      html  css  js  c++  java
  • 深入浅出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

    扫描二维码,关注个人公众号,可以第一时间得到最新的个人文章和内容推送

    本文版权归作者所有,转载请保留此声明和原文链接

  • 相关阅读:
    codeforces 814B An express train to reveries
    codeforces 814A An abandoned sentiment from past
    codeforces 785D D. Anton and School
    codeforces 785C Anton and Fairy Tale
    codeforces 791C Bear and Different Names
    AOP详解
    Spring集成JUnit测试
    Spring整合web开发
    IOC装配Bean(注解方式)
    IOC装配Bean(XML方式)
  • 原文地址:https://www.cnblogs.com/tiger-wang/p/14267942.html
Copyright © 2011-2022 走看看