当前位置: 移动技术网 > IT编程>开发语言>.net > 【ASP.NET Core学习】基础

【ASP.NET Core学习】基础

2019年10月29日  | 移动技术网IT编程  | 我要评论

金娜珠,大勐龙,迪拜王子的黄金车

新建项目时,程序入口调用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;
}

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

  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 

autofac.extensions.dependencyinjection

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网