【ASP.NET Core学习】基础
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; }
从上面代码看见这个方法帮我们处理的东西
- 设置根目录为当前目录
- 配置应用程序配置
- 配置日志配置
- 配置依赖注入
配置文件
{"setting": { "name": "wilson", "date": "2019-10-28" } }
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" } }
可以设置莫一类别的日志级别
"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>(); }
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
上一篇: 如何编写一个创建FTP站点的函数?
下一篇: 如何用Access加密页面?