zoukankan      html  css  js  c++  java
  • 【ASP.NET Core学习】基础

    新建项目时,程序入口调用CreateDefaultBuilder(args),下面是源代码
    public static IHostBuilder CreateDefaultBuilder(string[] args)
    {
        var builder = new HostBuilder();
    
        builder.UseContentRoot(Directory.GetCurrentDirectory());
        builder.ConfigureHostConfiguration(config =>
        {
            config.AddEnvironmentVariables(prefix: "DOTNET_");
            if (args != null)
            {
                config.AddCommandLine(args);
            }
        });
    
        builder.ConfigureAppConfiguration((hostingContext, config) =>
        {
            var env = hostingContext.HostingEnvironment;
    
            config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
    
            if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName))
            {
                var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
                if (appAssembly != null)
                {
                    config.AddUserSecrets(appAssembly, optional: true);
                }
            }
    
            config.AddEnvironmentVariables();
    
            if (args != null)
            {
                config.AddCommandLine(args);
            }
        })
        .ConfigureLogging((hostingContext, logging) =>
        {
            var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
    
            // IMPORTANT: This needs to be added *before* configuration is loaded, this lets
            // the defaults be overridden by the configuration.
            if (isWindows)
            {
                // Default the EventLogLoggerProvider to warning or above
                logging.AddFilter<EventLogLoggerProvider>(level => level >= LogLevel.Warning);
            }
    
            logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
            logging.AddConsole();
            logging.AddDebug();
            logging.AddEventSourceLogger();
    
            if (isWindows)
            {
                // Add the EventLogLoggerProvider on windows machines
                logging.AddEventLog();
            }
        })
        .UseDefaultServiceProvider((context, options) =>
        {
            var isDevelopment = context.HostingEnvironment.IsDevelopment();
            options.ValidateScopes = isDevelopment;
            options.ValidateOnBuild = isDevelopment;
        });
    
        return builder;
    }
    View Code

    从上面代码看见这个方法帮我们处理的东西

    1. 设置根目录为当前目录
    2. 配置应用程序配置
    3. 配置日志配置
    4. 配置依赖注入

    配置文件

    配置文件内容如下
    {"Setting": {
        "Name": "Wilson",
        "Date": "2019-10-28"    
      }
    }
     一、注入IConfiguration
    public IndexModel(IConfiguration config)
    {
      
    var name = config.GetSection("Setting").GetValue<string>("Name");
      var date = config.GetSection("Setting").GetValue<DateTime>("Date");
    }

    二、通过IOptions注入

    1. 在ConfigureServices添加Options支持和配置文件节点

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddOptions();
        services.Configure<Setting>(Configuration.GetSection("Setting"));
    }

    2. 构造函数里面注入IOptions

    public IndexModel(IOptions<Setting> option)
    {
        var setting = option.Value;
    
        var name = setting.Name;
        var date = setting.Date;
    }

    三、绑定到类

    public IndexModel(IConfiguration config)
    {
        var setting = new Setting();
        config.GetSection("Setting").Bind(setting);
    }

    或者

    public IndexModel(IConfiguration config)
    {
        var setting = config.GetSection("Setting").Get<Setting>();
    }

    四、页面读取配置文件

    @using Microsoft.Extensions.Configuration
    @inject IConfiguration Configuration
    
    <div class="text-center">
        <h3 class="color-red">@Configuration["Setting:Name"]</h3>
    </div>

    我个人推荐使用第二种方式去读取配置文件,因为它隐藏了如何读取配置文件,只需要获取我们关心的信息即可,第一,第三种都在不同地方使用硬编码的方式去读取(当然可以设置为常量),而且还有知道节点信息

    开发过程通常不同环境是读取不同配置,ASPNET Core提供了一个很方便的方法去实现

    截取源代码部分代码

    var env = hostingContext.HostingEnvironment;
    
    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
          .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

     它会除了加载appsettings.json外,还好加载当前环境的json配置文件

     我们只要设置当前环境环境变量(项目设置或者当前电脑环境变量添加ASPNETCORE_ENVIRONMENT)就能加载不同配置文件

    日志

    截取源代码部分代码

    var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
    
    // IMPORTANT: This needs to be added *before* configuration is loaded, this lets
    // the defaults be overridden by the configuration.
    if (isWindows)
    {
        // Default the EventLogLoggerProvider to warning or above
        logging.AddFilter<EventLogLoggerProvider>(level => level >= LogLevel.Warning);
    }
    
    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
    logging.AddConsole();
    logging.AddDebug();
    logging.AddEventSourceLogger();
    
    if (isWindows)
    {
        // Add the EventLogLoggerProvider on windows machines
        logging.AddEventLog();
    }

    除了配置基本信息,Windows操作系统Waring以上的日志还会写入到EventLog

    现在我们写几个日志试试,因为配置了,所以我们直接注入logger写日志

    public IndexModel(Logger<IndexModel> logger)
    {
        logger.LogDebug("This is Debug Message");
        logger.LogInformation("This is Information Message");
        logger.LogWarning("This is Warning Message");
        logger.LogError("This is Error Message");
    }

    看到控制台输出

     接着我们看看Evenlog有没有写入数

     我们看到警告基本以上的日志都写入了

    实际应用我们通常需要将日志写入文本文件,但ASPNET Core内置日志记录提供程序并没有提供文本文件的程序,但是我们可以使用第三方日志组件(例如log4net)

    1. Nuget添加log4net(Microsoft.Extensions.Logging.Log4Net.AspNetCore)

    2. 调用日志记录框架提供的 ILoggerFactory 扩展方法。

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddLog4Net();
        .....
    }

     访问一下,看看写入日志

    可以看到,除了中间那段是我们写入的,其他都是系统的日志

    在源代码里面可以看到,系统是添加Logging节点的配置信息,里面可以指定日志类别

    "Logging": {
      "LogLevel": {
        "Default": "Debug",
        "System": "Warning",
        "Microsoft": "Warning"
      }
    }
     指定System和Microsoft类别为Warning,只有高于这个级别才会输出到日志

     可以设置莫一类别的日志级别

    "Logging": {
      "LogLevel": {
        "Default": "Debug",
        "System": "Warning",
        "Microsoft": "Information",
        "Microsoft.AspNetCore.Mvc":"Warning"
      }
    }

     只能设置大的级别再设置小级别才有效,即若只设置Microsoft.AspNetCore.Mvc,不设置Microsoft就不起效果

    依赖注入

    ASP.NET Core 支持依赖关系注入 (DI) 软件设计模式,这是一种在类及其依赖关系之间实现控制反转 (IoC) 的技术。

    在CreateDefaultBuilder最后是一个扩展方法,使用默认的DefaultServiceProviderFactory

    ASP.NET Core 提供三种注册方法

    方法描述适合场景
    AddTransient
     每次从服务容器进行请求时都是新建 轻量级、 无状态的服务
    AddScoped
     每次请求/连接是同一个对象 Http请求需要保持同一个对象
    AddSingleton
     单例 单例对象 

    一、添加服务

    public void ConfigureServices(IServiceCollection services)
    {
      ...
      services.AddSingleton
    <IServiceSingleton, ServiceSingleton>(); services.AddScoped<IServiceScoped, ServiceScoped>(); services.AddTransient<IServicesTransient, ServicesTransient>(); services.AddTransient<IMyService, MyService>(); }
    二、 获取服务方式
    1. 构造函数获取
    public IndexModel(IServicesTransient servicesTransient)
    {
    }

     2. 通过IHttpContextAccessor获取

      2.1 注入IHttpContextAccessor

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    }

       2.2 通过RequestServices获取

    var service = accessor.HttpContext.RequestServices.GetService<IMyService>();
    service.Run();

    三、使用第三方容器

    内置的容器实现最基本的注入方式,已经能满足大部分项目需求。但是有时候可能需要特殊的需求,例如属性注入、基于名称的注入、自定义生存期管理等功能时,内置的容器不支持这些功能。下面介绍如何替换内置容器,以Autofac为例

    1. nuget 添加Autofac.Extensions.DependencyInjection

    2. Program替换容器

    public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                    .UseServiceProviderFactory(new AutofacServiceProviderFactory())

    3. Startup类添加方法ConfigureContainer 

    public void ConfigureContainer(ContainerBuilder builder)
    {
        builder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>();
    
        builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly())
                .Where(m => m.Name.Contains("Service"))
                .AsImplementedInterfaces()
                .InstancePerLifetimeScope();
    }

    这是ASPNET Core 3.0+版本替换Autofac方法,3.0不支持返回IServiceProvider 

  • 相关阅读:
    JavaScript对原始数据类型的拆装箱操作
    Javascript继承(原始写法,非es6 class)
    动态作用域与词法作用域
    自行车的保养
    探索JS引擎工作原理 (转)
    C语言提高 (7) 第七天 回调函数 预处理函数DEBUG 动态链接库
    C语言提高 (6) 第六天 文件(续) 链表的操作
    C语言提高 (5) 第五天 结构体,结构体对齐 文件
    C语言提高 (4) 第四天 数组与数组作为参数时的数组指针
    C语言提高 (3) 第三天 二级指针的三种模型 栈上指针数组、栈上二维数组、堆上开辟空间
  • 原文地址:https://www.cnblogs.com/WilsonPan/p/11751028.html
Copyright © 2011-2022 走看看