• ASP.NET CORE


    ASP.NET Core 是一个新的开源和跨平台的框架,用于构建如 Web 应用、物联网(IoT)应用和移动后端应用等连接到互联网的基于云的现代应用程序。ASP.NET Core 应用可运行于 .NET Core 和完整的 .NET Framework 之上。 构建它的目的是为那些部署在云端或者内部运行(on-premises)的应用提供一个优化的开发框架。它由最小开销的模块化的组件构成,因此在构建你的解决方案的同时可以保持灵活性。你可以在 Windows、Mac 和 Linux 上跨平台的开发和运行你的 ASP.NET Core 应用。 ASP.NET Core 开源在 GitHub 上。

    C#新特性

    这里记录下在C#6.0和C#7.0下常用的一些新特性

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using static System.Math;//静态导入 static 类
    
    namespace Ruanmou.Core.ConsoleProject
    {
        /// <summary>
        /// C#6 新语法
        /// </summary>
        public class SharpSix
        {
            #region 自动属性初始化(Auto-property initializers)
            public string Name { get; set; } = "summit";
            public int Age { get; set; } = 22;
            public DateTime BirthDay { get; set; } = DateTime.Now.AddYears(-20);
            public IList<int> AgeList
            {
                get;
                set;
            } = new List<int> { 10, 20, 30, 40, 50 };
            #endregion
    
            public void Show(People peopleTest)
            {
                #region 字符串嵌入值(String interpolation)
                Console.WriteLine($"年龄:{this.Age}  生日:{this.BirthDay.ToString("yyyy-MM-dd")}");
                Console.WriteLine($"年龄:{{{this.Age}}}  生日:{{{this.BirthDay.ToString("yyyy -MM-dd")}}}");
    
                Console.WriteLine($"{(this.Age <= 22 ? "小鲜肉" : "老鲜肉")}");
                #endregion
    
                #region 导入静态类(Using Static)
                Console.WriteLine($"之前的使用方式: {Math.Pow(4, 2)}");
                Console.WriteLine($"导入后可直接使用方法: {Pow(4, 2)}");
                #endregion
    
                #region 空值运算符(Null-conditional operators)
                int? iValue = 10;
                Console.WriteLine(iValue?.ToString());//不需要判断是否为空
                string name = null;
                Console.WriteLine(name?.ToString());
                #endregion
    
                #region 对象初始化器(Index Initializers)
                IDictionary<int, string> dictOld = new Dictionary<int, string>()
                {
                    { 1,"first"},
                    { 2,"second"}
                };
    
                IDictionary<int, string> dictNew = new Dictionary<int, string>()
                {
                    [4] = "first",
                    [5] = "second"
                };
    
                #endregion
    
                #region nameof表达式 (nameof expressions)
                Console.WriteLine(nameof(peopleTest)); //获取peopleTest这个字符串
                #endregion
            }
    
            #region 在属性/方法里使用Lambda表达式(Expression bodies on property-like function members)
            public string NameFormat => string.Format("姓名: {0}", "summit");
            public void Print() => Console.WriteLine(Name);
            #endregion
        }
    }
    
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Ruanmou.Core.ConsoleProject
    {
        /// <summary>
        /// c#7新语法
        /// </summary>
        public class SharpSeven
        {
            public void Show()
            {
                #region out参数
                {
                    this.DoNoting(out int x, out int y);
                    Console.WriteLine(x + y);
    
                    this.DoNoting(out var l, out var m);
    
                }
                //Console.WriteLine(x + y);
                #endregion
    
                #region 模式
                this.PrintStars(null);
                this.PrintStars(3);
    
                this.Switch(null);
                this.Switch("ElevenEleven");
                this.Switch("Eleven");
                #endregion
    
                #region 元组
                {
                    var result = this.LookupName(1);
                    Console.WriteLine(result.Item1);
                    Console.WriteLine(result.Item2);
                    Console.WriteLine(result.Item3);
                }
                #endregion
    
                #region 局部函数
                {
                    Add(3);
                    int Add(int k)//闭合范围内的参数和局部变量在局部函数的内部是可用的,就如同它们在 lambda 表达式中一样。
                    {
                        return 3 + k;
                    }
                }
                #endregion
    
                #region 数字分隔号
                long big = 100_000;
                #endregion
    
            }
    
            /// <summary>
            /// System.ValueTuple 需要安装这个nuget包
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            private (string, string, string) LookupName(long id) // tuple return type
            {
                return ("first", "middle", "last");
            }
    
            /// <summary>
            /// 具有模式的 IS 表达式
            /// </summary>
            /// <param name="o"></param>
            public void PrintStars(object o)
            {
                if (o is null) return;     // 常量模式 "null"
                if (!(o is int i)) return; // 类型模式 定义了一个变量 "int i"
                Console.WriteLine(new string('*', i));
            }
    
            /// <summary>
            /// 可以设定任何类型的 Switch 语句(不只是原始类型)
            /// 模式可以用在 case 语句中
            /// Case 语句可以有特殊的条件
            /// </summary>
            /// <param name="text"></param>
            private void Switch(string text)
            {
                int k = 100;
                switch (text)
                {
                    case "ElevenEleven" when k > 10:
                        Console.WriteLine("ElevenEleven");
                        break;
                    case "Eleven" when text.Length < 10:
                        Console.WriteLine("ElevenEleven");
                        break;
                    case string s when s.Length > 7://模式
                        Console.WriteLine(s);
                        break;
                    default:
                        Console.WriteLine("default");
                        break;
                    case null:
                        Console.WriteLine("null");
                        break;
                }
            }
    
            private void DoNoting(out int x, out int y)
            {
                x = 1;
                y = 2;
            }
        }
    }
    
    

    应用程序剖析

    一个 ASP.NET Core 应用其实就是一个在其 Main 方法中创建一个 web 服务器的简单控制台应用程序:

    using System;
    using Microsoft.AspNetCore.Hosting;
    
    namespace aspnetcoreapp
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var host = new WebHostBuilder()
                    .UseKestrel()
                    .UseStartup<Startup>()
                    .Build();
    
                host.Run();
            }
        }
    }
    

    Main 调用遵循 builder 模式的 WebHostBuilder ,用于创建一个 web 应用程序宿主。这个 builder 有些用于定义 web 服务器 (如 UseKestrel)和 startup 类型( UseStartup)的方法。在上面的示例中,web 服务器 Kestrel 被启用,但是你也可以指定其它 web 服务器。
    WebHostBuilder 提供了一些可选方法,其中包括寄宿在 IIS 和 IIS Express 中的 UseIISIntegration 和用于指定根内容目录的 UseContentRoot。Build 和 Run 方法构建了用于宿主应用程序的 IWebHost 然后启动它来监听传入的 HTTP 请求。

    Startup

    WebHostBuilder 的 UseStartup 方法为你的应用指定了 Startup 类。
    Startup 类是用来定义请求处理管道和配置应用需要的服务。 Startup 类必须是公开的(public)并且包含如下方法:

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
        }
    
        public void Configure(IApplicationBuilder app)
        {
        }
    }
    

    ConfigureServices 定义你的应用所使用的服务(例如 ASP.NET MVC Core framework、Entity Framework Core、Identity 等等)
    Configure 定义你的请求管道中的 中间件(middleware)

    服务(Services)

    服务是应用中用于通用调用的组件。服务通过依赖注入获取并使用。 ASP.NET Core 内置了一个简单的控制反转(IoC) 容器,它默认支持构造器注入,并且可以方便的替换成你自己选用的 IoC 容器。由于它的松耦合特性,依赖注入(DI) 使服务在整个应用中都可以使用。例如,Logging 在你整个应用中都可用。查看 Dependency Injection 获取更多信息。

    中间件(Middleware)

    在 ASP.NET Core 中,你可以使用 Middleware 构建你的请求处理管道。 ASP.NET Core 中间件为一个 HttpContext 执行异步逻辑,然后按顺序调用下一个中间件或者直接终止请求。一般来说你要使用一个中间件,只需要在 Configure 方法里调用 IApplicationBuilder 上一个对应的 UseXYZ 扩展方法。

    ASP.NET Core 带来了丰富的内置中间件:

    • 静态文件(Static files)
    • 路由(Routing)
    • 身份验证(Authentication)
      你也可以创建你自己的自定义中间件。

    你也可以在 ASP.NET Core 中使用任何基于 OWIN 的中间件。

    服务器(Servers)

    ASP.NET Core 托管模式并不直接监听请求;而是依赖于一个 HTTP server 实现来转发请求到应用程序。这个被转发的请求会以一组 feature 接口的形式被包装,然后被应用程序组合到一个 HttpContext中去。 ASP.NET Core 包含了一个托管的跨平台 web 服务器,被称为 Kestrel,它往往会被运行在一个如 IIS 或者 nginx 的生产 web 服务器之后。

    内容根目录(Content root)

    内容根目录是应用程序所用到的所有内容的根路径,例如它的 views 和 web 内容。内容根目录默认与宿主应用的可执行程序的应用根目录相同;一个替代的地址可以通过 WebHostBuilder 来设置。

    Web根目录(Web root)

    你的应用的Web根目录(Web root)是你项目中所有公共的、静态的资源,如 css、js 和 图片文件的目录。静态文件中间件将默认只发布 Web 根目录(Web root)和其子目录中的文件。 Web 根目录(Web root)默认为 /wwwroot,但是你也可以通过 WebHostBuilder 来指定另外一个地址。

    配置(Configuration)

    ASP.NET Core 使用了一个新的配置模型用于处理简单的键值对。新的配置模型并非基于System.Configuration 或者 web.config ;而是从一个有序的配置提供者集合拉取数据。内置的配置提供者支持多种不同的文件格式如(XML,JSON, INI)和用于支持基于环境的配置环境变量。
    默认的MVC项目是通过 Asp.net Core 预制的"空"模板创建的,项目中已经有一个 appsettings.json 的文件了。 我们可以对文件补充键值对,在StartUp类,Configure方法中就可以直接读取配置。

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory factory)
    {
        #region 配置文件的读取
        //xml path
        Console.WriteLine($"option1 = {this.Configuration["Option1"]}");
        Console.WriteLine($"option2 = {this.Configuration["option2"]}");
        Console.WriteLine(
            $"suboption1 = {this.Configuration["subsection:suboption1"]}");
        Console.WriteLine("Wizards:");
        Console.Write($"{this.Configuration["wizards:0:Name"]}, ");
        Console.WriteLine($"age {this.Configuration["wizards:0:Age"]}");
        Console.Write($"{this.Configuration["wizards:1:Name"]}, ");
        Console.WriteLine($"age {this.Configuration["wizards:1:Age"]}");
        #endregion
    }
    

    依赖注入

    在.NET Core中DI的核心分为两个组件:IServiceCollection和 IServiceProvider。
    IServiceCollection 负责注册;IServiceProvider 负责提供实例。通过默认的 ServiceCollection(在Microsoft.Extensions.DependencyInjection命名空间下)有三个方法:

    var serviceCollection = new ServiceCollection()
      .AddTransient<ILoginService, EFLoginService>()
      .AddSingleton<ILoginService, EFLoginService>()
      .AddScoped<ILoginService, EFLoginService>();
    

    对应的实例生命周其包括三种:
    Transient: 每一次GetService都会创建一个新的实例
    Scoped: 在同一个Scope内只初始化一个实例 ,可以理解为( 每一个request级别只创建一个实例,同一个http request会在一个 scope内)
    Singleton :整个应用程序生命周期以内只创建一个实例

    ASP.NET Core可以在Startup.cs的 ConfigureService中配置DI,大家看到 IServiceCollection这个参数应该就比较熟悉了。

    Controller中使用时,一般可以通过构造函数或者属性来实现注入,但是官方推荐是通过构造函数。这也是所谓的显式依赖。

    private ILoginService<ApplicationUser> _loginService;
    public AccountController(
      ILoginService<ApplicationUser> loginService)
    {
      _loginService = loginService;
    }
    

    参考:
    ASP.NET Core 介绍
    解读ASP.NET 5 & MVC6系列(7):依赖注入
    全面理解 ASP.NET Core 依赖注入

  • 相关阅读:
    poj 1262 地板覆盖问题
    混合图 (Standard IO)
    matrix
    麻将 (Standard IO)
    C#多线程编程之:异步事件调用
    使用线程池与专用线程
    C#多线程编程之:Timer(定时器)使用示例
    C#多线程编程之:异步方法调用
    WCF 快速入门
    c#实现每隔一段时间执行代码(多线程)
  • 原文地址:https://www.cnblogs.com/hellojamest/p/15067524.html
Copyright © 2020-2023  润新知