有时候,越是基础的东西,越是有人不明白。

前几天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。不用太纠结,微软的命名规则而已。

这就是控制台应用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

喜欢就来个三连,让更多人因你而受益

深入浅出Dotnet Core的项目结构变化相关推荐

  1. 国产中标麒麟Linux部署dotnet core 环境并运行项目 (三) 部署运行WEB API项目

    部署dotnet Core Web API 上一步的文章,是我们公司最核心的一个ORM组件,在中标麒麟系统完成了一个插入数据的任务,这一步是将正式的从dot net framework 迁移到 dot ...

  2. 手把手教你使用spring cloud+dotnet core搭建微服务架构:服务治理(-)

    背景 公司去年开始使用dotnet core开发项目.公司的总体架构采用的是微服务,那时候由于对微服务的理解并不是太深,加上各种组件的不成熟,只是把项目的各个功能通过业务层面拆分,然后通过nginx代 ...

  3. [SSCore] 开源dotnet core 版本 SuperSocket

    前言碎语 最近一直在做旧版本dotnet 程序迁移至dotnet core的工作, 非常欣慰dotnet社区的蓬勃发展, 目前大部分的第三方类库或开源代码都有了dotnet core版本 或者可以方便 ...

  4. DotNet Core 介绍

    前言 asp.net core rtm 6月底即将发布,自己也想着为社区做点共享,刚好最近不太忙,看到社区的小伙伴们都在为dotnet core的推广而贡献力量,项目中刚好在用rc2版本,就多写些文章 ...

  5. TchApp 为dotnet core配个UI,项目已托管github

    TchApp 为dotnet core配个UI,项目已托管github https://github.com/tnelab/tchapp 项目组需要里的帮助! 转载于:https://www.cnbl ...

  6. 使用docker生成dotnet core项目镜像

    docker生成dotnet core镜像 使用docker生成dotnet core项目镜像.需要编写Dockerfile文件.编写方法有两种,如下: 使用docker生成dotnet core项目 ...

  7. 【.Net Core】把dotnet core 项目部署到docker

    把dotnet core 项目部署到docker Docker Dockerfile 部署到Centos8 发布 运行容器: 容器内运行命令 Docker Dockerfile # 引入镜像,低版本 ...

  8. DOCKER上运行DOTNET CORE

    DOCKER上运行DOTNET CORE 原文:DOCKER上运行DOTNET CORE 下载microsoft/dotnet镜像 运行命令: docker pull microsoft/dotnet ...

  9. k8s pod部署到不同node_部署Dotnet Core应用到Kubernetes(一) - 老王Plus

    最近闲了点,写个大活:部署Dotnet应用到K8s. 写在前边的话 一直想完成这个主题.但这个主题实在太大了,各种拖延症的小宇宙不时爆发一下,结果就拖到了现在. 这个主题,会是一个系列.在这个系列中, ...

最新文章

  1. 我看过的C#方面的好文章
  2. UVA11427玩纸牌(全概率+递推)
  3. WZJ的数据结构(零)KMP
  4. python- 进阶 与flask的搭配使用---定时任务框架APScheduler学习详解
  5. 460. LFU 缓存
  6. lisp读取天正轴号_第2天:Python 基础语法
  7. django配置随时执行的脚本,使用运行时的manage环境执行程序
  8. 海报psd素材模板|周年海报,仪式感值得珍藏
  9. QT5.10+MinGW+OpenCV3.4.2编译
  10. 进程外session(session保存在sqlserver)
  11. ITIL学习笔记——核心流程之:服务级别管理
  12. 论文笔记27 -- (视频压缩)Learned Video Codec with Enriched Reconstruction for CLIC P-frame Coding
  13. python zlib_【python】使用zlib进行压缩解压
  14. vasp计算压电系数_求助DFTP算出来的压电系数 - 第一原理 - 小木虫 - 学术 科研 互动社区...
  15. ubuntu如何查看当前的ROS发行版本
  16. sae bae微信上墙|微信墙完美版(php源码),最新微信表白墙源码 微信互动墙 微信留言板 微信留言墙源码 - A保站...
  17. 插入u盘有图标但计算机没盘,没插U盘却有U盘图标显示的原因和解决方法
  18. 【Unity 3D游戏开发】在Unity使用NoSQL数据库方法介绍
  19. 浮点数与IEEE754
  20. 给生活添加更多乐趣!便携实用的迷你打印机-咕咕机GT1体验

热门文章

  1. JS的常用正则表达式 验证密码
  2. Sql—表格的建立,删除,数据的建立与删除-总结篇
  3. Java通过Executors提供四种线程池
  4. Linux常用开发环境软件-Redis安装(docker环境下)
  5. Java Decompiler(Java反编译工具)
  6. CAP理论与MongoDB一致性、可用性的一些思考
  7. 数据分析入门_char01
  8. [HTML5]3D标签云
  9. MySql:从任何主机授予根用户登录权限
  10. 固态硬盘可靠性_您可以通过使用较少的总容量来提高硬盘的可靠性吗?