ps:废话不多说。直接上代码:源码地址:https://github.com/786744873/Asp.Net-Core-2.1-All-Demos/tree/master/src

Configuration的配置

说明:基于三种方式的读取配置文件以及自定义读取自定义配置文件

文件结构

代码

PropertiesConfigurationProvider.cs

public class PropertiesConfigurationProvider:ConfigurationProvider
{
string _path = string.Empty;
public PropertiesConfigurationProvider(string path)
{
this._path = path;
} /// <summary>
/// 用于解析1.properties
/// </summary>
public override void Load()
{
var lines = File.ReadAllLines(this._path); var dict = new Dictionary<string, string>(); foreach (var line in lines)
{
var items = line.Split('=');
dict.Add(items[], items[]);
} this.Data = dict;
}
}

PropertiesConfigurationSource.cs

public class PropertiesConfigurationSource : IConfigurationSource
{ string _path = string.Empty;
public PropertiesConfigurationSource(string path)
{
this._path = path;
} public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new PropertiesConfigurationProvider(_path);
}
}

PropertiesConfigurationExtensions.cs

public static class PropertiesConfigurationExtensions
{
public static IConfigurationBuilder AddPropertiesFile(this IConfigurationBuilder builder, string path)
{
builder.Add(new PropertiesConfigurationSource(path));
return builder;
}
}

1.properties

port=
host=127.0.0.1

appsettings.json

{
"mysql": {
"host": "127.0.0.1",
"port":
},
"shopidlist": [
{ "entid": },
{ "entid": }
]
}

Program.cs

class Program
{
static void Main(string[] args)
{
IConfiguration Configuration = new ConfigurationBuilder()
.SetBasePath(Environment.CurrentDirectory)
.AddJsonFile("appsettings.json", optional:true,reloadOnChange:true)
.AddPropertiesFile("1.properties")//加载自定义文件
.Build(); Appsettings appsettings = new Appsettings();
Configuration.Bind(appsettings); Console.WriteLine(appsettings.mysql.port); Console.WriteLine(Configuration["mysql:port"]); Console.WriteLine(Configuration.GetValue<int>("mysql:port")); Console.WriteLine(Configuration.GetSection("mysql").GetSection("port").Value);
//读取自定义文件
Console.WriteLine(Configuration["host"]); Console.Read();
}
} public class Appsettings
{
public Mysql mysql { get; set; }
public Shopidlist[] shopidlist { get; set; }
} public class Mysql
{
public string host { get; set; }
public int port { get; set; }
} public class Shopidlist
{
public int entid { get; set; }
}

CollectionService注入

文件结构

代码

Program.cs

class Program
{
static void Main(string[] args)
{
//IOC容器
ServiceCollection services = new ServiceCollection(); //注册服务
services.AddScoped<IFlay, Pig>(); //注册日志服务
services.AddLogging(); var provider = services.BuildServiceProvider(); provider.GetService<ILoggerFactory>().AddConsole(LogLevel.Debug); var fly = provider.GetService<IFlay>(); fly.Flay(); }
} public interface IFlay
{
void Flay();
} public class Pig : IFlay
{
ILogger<Pig> logger = null; public Pig(ILoggerFactory loggerFactory)
{
logger=loggerFactory.CreateLogger<Pig>();
} public void Flay()
{
logger.LogInformation("这是Console日志");
Console.WriteLine("风口来了,猪都会飞了!");
}
}

AOP AspectCore

文件结构

代码

Program.cs

//https://github.com/dotnetcore/AspectCore-Framework
class Program
{
static void Main(string[] args)
{
ServiceCollection services = new ServiceCollection(); //注册AspectCore动态代理服务
services.AddDynamicProxy(); services.AddTransient<IMySql, MySql>(); var provider= services.BuildDynamicProxyServiceProvider(); var mysql = provider.GetService<IMySql>(); //走业务逻辑
var msg= mysql.GetData();
Console.WriteLine(msg); //走缓存
msg = mysql.GetData();
Console.WriteLine(msg); }
} public class MysqlInterceptorAttribute : AbstractInterceptorAttribute
{
private Dictionary<string, string> cacheDict = new Dictionary<string, string>(); public override Task Invoke(AspectContext context, AspectDelegate next)
{ //用id作为cachekey
var cacheKey = string.Join(",", context.Parameters);
if (cacheDict.ContainsKey(cacheKey))
{
context.ReturnValue = cacheDict[cacheKey];
return Task.CompletedTask;
} var task = next(context);
//ReturnValue实际上就是一个传递值的媒介
var cacheValue = context.ReturnValue; cacheDict.Add(cacheKey, $"from Cache:{cacheValue.ToString()}"); return task; //Console.WriteLine("开始记录日志。。。。");
//var task = next(context);
//Console.WriteLine("结束记录日志。。。。");
//return task;
}
} public interface IMySql
{
[MysqlInterceptor]
string GetData(int id);
} public class MySql : IMySql
{
public string GetData(int id)
{
var msg = $"已经获取到id={id}的数据";
//Console.WriteLine(msg);
return msg;
}
}

MemoryCache

文件结构

代码

Program.cs

class Program
{
static void Main(string[] args)
{ {//cache的最大限度为100 MemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions()
{
SizeLimit =
}); for (int i = ; i < ; i++)
{
memoryCache.Set<string>(i.ToString(), i.ToString(), new MemoryCacheEntryOptions()
{
Size =
}); Console.WriteLine(memoryCache.Count);
}
} {//被动过期,设置过期回调 MemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions()
{ }); var cacheOptions = new MemoryCacheEntryOptions
{
AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(),//3秒过期
};
cacheOptions.RegisterPostEvictionCallback((key, value, reason, obj) =>
{
Console.WriteLine(reason);
Console.WriteLine("执行过期回调");
}); memoryCache.Set("key", "value", cacheOptions); Console.WriteLine("3秒后过期将执行回调");
while (true)
{
Thread.Sleep();
Console.WriteLine(memoryCache.Get<string>("key"));
}
Console.ReadKey();
} {//主动过期(10秒被动过期,2秒主动使用token让他过期) CancellationTokenSource tokenSource = new CancellationTokenSource();
MemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions()
{ }); var cacheOptions = new MemoryCacheEntryOptions
{
AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(),//10秒过期
};
cacheOptions.AddExpirationToken(new CancellationChangeToken(tokenSource.Token));//加入Token
cacheOptions.RegisterPostEvictionCallback((key, value, reason, obj) =>
{
Console.WriteLine(reason);
Console.WriteLine("执行过期回调");
}); memoryCache.Set("key", "value", cacheOptions); Console.WriteLine("10秒后过期将执行回调"); tokenSource.CancelAfter(TimeSpan.FromSeconds());
while (true)
{
Thread.Sleep();
Console.WriteLine(memoryCache.Get<string>("key"));
}
Console.ReadKey();
}
}
}

Redis MongoDB

文件结构

代码

Program.cs

class Program
{
static void Main(string[] args)
{
//Redis
{
RedisCache redisCache = new RedisCache(new RedisCacheOptions()
{
Configuration = "127.0.0.1:6379",
InstanceName = "test"
}); //在Redis中是以Hash的模式存放的
redisCache.SetString("username", "jack", new DistributedCacheEntryOptions
{
AbsoluteExpiration = DateTime.Now.AddDays(),
}); var info = redisCache.GetString("username"); Console.WriteLine(info);
} //MongoDB
{
MongoDBCache mongoDBCache = new MongoDBCache(new MongoDBCacheOptions()
{
ConnectionString = "mongodb://127.0.0.1:27017",
DatabaseName = "mydb",
CollectionName = "mytest"
}); mongoDBCache.Set("username", Encoding.UTF8.GetBytes("jack"), new DistributedCacheEntryOptions {
AbsoluteExpiration = DateTime.Now.AddDays()
}); var info= Encoding.UTF8.GetString(mongoDBCache.Get("username"));
Console.WriteLine(info);
} }
}

Mysql.Data Dapper

文件结构

代码

class Program
{
static void Main(string[] args)
{
//MySql.Data
{
var connectString = "server=127.0.0.1;por=3306;userid=root;pwd=123456;database=datamip;SslMode=none;";
//MySqlConnection mySqlConnection = new MySqlConnection(connectString); //select
var ds = MySqlHelper.ExecuteDataset(connectString, "select * from users"); //select2
var reader = MySqlHelper.ExecuteReader(connectString, "select * from users");
var user = new Users();
while (reader.Read())
{
user.UserId = reader.GetInt32("UserID");
user.UserNick = reader.GetString("UserNick");
user.LoginIP = reader.GetString("LoginIP");
user.Email = reader.GetString("Email");
}
reader.Close(); //update
var result = MySqlHelper.ExecuteNonQuery(connectString, "update users set Email='786744873@qq.com' where UserID=1");
} //Dapper
{
var connectString = "server=127.0.0.1;por=3306;userid=root;pwd=123456;database=datamip;SslMode=none;";
MySqlConnection mySqlConnection = new MySqlConnection(connectString); //select
var userList = mySqlConnection.Query<Users>("select * from users where UserID=@UserID",new { UserID= }); //update
var nums = mySqlConnection.Execute("update users set Email='786744873@qq.com' where UserID=1");
} } class Users
{
public int UserId { get; set; }
public string UserNick { get; set; }
public string LoginIP { get; set; }
public string Email { get; set; }
}
}

nohup supervisord部署Unbuntu

不得不说Ubuntu18.04版本是个巨坑。还是老老实实用16.04吧,错了,是VirtualBox是个巨坑,这wtf软件各种问题,浪费我几天时间,艹

文件结构

代码

ConfigurationManager.cs

public class ConfigurationManager
{
public static IConfigurationRoot Configuration
{
get
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile(string.Format("appsettings.{0}.json", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")),optional:true,reloadOnChange:true)
.AddJsonFile(string.Format("ops.{0}.json", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")),optional:true,reloadOnChange:true)
.Build();
return configuration;
}
}
}

Program.cs

class Program
{
static void Main(string[] args)
{
var tokenSource = new CancellationTokenSource(); Task.Factory.StartNew(() =>
{
while (!tokenSource.IsCancellationRequested)
{
Console.WriteLine($"{DateTime.Now}:业务逻辑处理中");
Thread.Sleep();
}
}).ContinueWith(t =>
{
Console.WriteLine("服务安全退出!");
Environment.Exit();//强制退出
}); Console.WriteLine("服务成功开启"); while (!"Y".Equals(ConfigurationManager.Configuration["isquit"],StringComparison.InvariantCultureIgnoreCase))
{
Thread.Sleep();
} tokenSource.Cancel();
}
}

ops.Development.json  ||  ops.Production.json

{
"isquit": "N"
}

部署过程

直接发布,发布以及虚拟机安装参照之前的博客:Virtual Box虚拟机Ubuntu18.X系统安装及Mysql基本开发配置,这里主要讲如何进行持久化

ubuntu16.04开机提示:检测到系统程序出现问题

打开终端,输入 sudo gedit /etc/default/apport 

把enabled=1改成enabled=

方案一:nohub部署

先执行 nohup dotnet 程序集名称 &

nohup dotnet ConsoleApp7.dll &  #(符号&使程序在后台运行)
exit #(退出nohup模式)

然后输入 exit 进行退出,不然的话后台进程会被终结

启动后,会将程序运行输出记录在当前目录下的nohup.out文件下,如果当前目录不可写,则会被记录在Home目录下的nohup.out文件中

nohup dotnet ConsoleApp7.dll > my_nohup.log 2>&1 & #(将日志输出在my_nohup.log文件中,并将stderr重定向至stdout)

查看dotnet进程

ps -ef |grep dotnet

查看后10行nohup输出

tail /home/wyt/nohup.out

查看运行的后台进程

ps -ef | grep dotnet

停止程序

kill -  #(根据进程号关闭程序)

方案二:supervisord部署

安装

ubuntu安装:
sudo apt-get install supervisor
centos安装:
yum install -y supervisor

安装成功后,会在 /etc/supervisor 目录下,生成 supervisord.conf 配置文件。

你也可以使用 echo_supervisord_conf > supervisord.conf 命令,生成默认的配置文件(不建议,内容比较多)。

supervisord.conf 示例配置:

; supervisor config file

[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod= ; sockef file mode (default ) [supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) ; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket ; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves. [include]
files = /etc/supervisor/conf.d/*.conf

进程配置会读取 /etc/supervisor/conf.d 目录下的 *.conf 配置文件,我们在此目录下创建一个 ConsoleApp7.conf 进程配置文件:

[program:ConsoleApp7]
directory=/data/output
command=/usr/bin/dotnet /data/output/ConsoleApp7.dll
autostart=true
autorestart=true
startretries=
redirect_stderr=true
stdout_logfile=/data/output/logs/out.log
stderr_logfile=/data/output/logs/out.log
environment=ASPNETCORE_ENVIRONMENT="Development"

需要注意的是,如果不是 root 账号,需要对这些目录进行权限设置,要不然会报一些错误(一定要在 root 账号下进行配置,要不然一系列权限引起的问题

ASP.NET Core 2.1的配置、AOP、缓存、部署、ORM、进程守护、Nginx、Polly【源码】的更多相关文章

  1. asp.net core 2.0 web api + Identity Server 4 + angular 5 可运行前后台源码

    前台使用angular 5, 后台是asp.net core 2.0 web api + identity server 4. 从头编写asp.net core 2.0 web api 基础框架: 第 ...

  2. 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之三 —— 配置

    ==== 目录 ==== 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之一 —— 开篇 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之二 —— ...

  3. [ASP.NET Core 3框架揭秘] 配置[1]:读取配置数据[上篇]

    提到"配置"二字,我想绝大部分.NET开发人员脑海中会立即浮现出两个特殊文件的身影,那就是我们再熟悉不过的app.config和web.config,多年以来我们已经习惯了将结构化 ...

  4. [ASP.NET Core 3框架揭秘] 配置[2]:读取配置数据[下篇]

    [接上篇]提到“配置”二字,我想绝大部分.NET开发人员脑海中会立即浮现出两个特殊文件的身影,那就是我们再熟悉不过的app.config和web.config,多年以来我们已经习惯了将结构化的配置定义 ...

  5. [ASP.NET Core 3框架揭秘] 配置[5]:配置数据与数据源的实时同步

    在<配置模型总体设计>介绍配置模型核心对象的时候,我们刻意回避了与配置同步相关的API,现在我们利用一个独立文章来专门讨论这个话题.配置的同步涉及到两个方面:第一,对原始的配置源实施监控并 ...

  6. [ASP.NET Core 3框架揭秘] 配置[3]:配置模型总体设计

    在<读取配置数据>([上篇],[下篇])上面一节中,我们通过实例的方式演示了几种典型的配置读取方式,接下来我们从设计的维度来重写认识配置模型.配置的编程模型涉及到三个核心对象,分别通过三个 ...

  7. [ASP.NET Core 3框架揭秘] 配置[7]:多样化的配置源[中篇]

    物理文件是我们最常用到的原始配置载体,而最佳的配置文件格式主要有三种,它们分别是JSON.XML和INI,对应的配置源类型分别是JsonConfigurationSource.XmlConfigura ...

  8. [ASP.NET Core 3框架揭秘] 配置[6]:多样化的配置源[上篇]

    .NET Core采用的这个全新的配置模型的一个主要的特点就是对多种不同配置源的支持.我们可以将内存变量.命令行参数.环境变量和物理文件作为原始配置数据的来源.如果采用物理文件作为配置源,我们可以选择 ...

  9. [ASP.NET Core 3框架揭秘] 配置[4]:将配置绑定为对象

    虽然应用程序可以直接利用通过IConfigurationBuilder对象创建的IConfiguration对象来提取配置数据,但是我们更倾向于将其转换成一个POCO对象,以面向对象的方式来使用配置, ...

  10. 【ASP.NET Core】自定义的配置源

    本文的主题是简单说说如何实现 IConfigurationSource.IConfigurationProvider 接口来自定义一个配置信息的来源,后面老周给的示例是实现用 CSV 文件进行应用配置 ...

随机推荐

  1. Java Fork/Join 框架

    简介 从JDK1.7开始,Java提供Fork/Join框架用于并行执行任务,它的思想就是讲一个大任务分割成若干小任务,最终汇总每个小任务的结果得到这个大任务的结果. 这种思想和MapReduce很像 ...

  2. bzoj5342 CTSC2018 Day1T3 青蕈领主

    首先显然的是,题中所给出的n个区间要么互相包含,要么相离,否则一定不合法. 然后我们可以对于直接包含的关系建出一棵树,于是现在的问题就是给n个节点分配权值,使其去掉最后一个点后不存在非平凡(长度大于1 ...

  3. Java开源生鲜电商平台-性能优化以及服务器优化的设计与架构(源码可下载)

    Java开源生鲜电商平台-性能优化以及服务器优化的设计与架构(源码可下载) 说明:Java开源生鲜电商平台-性能优化以及服务器优化的设计与架构,我采用以下三种维度来讲解 1.  代码层面. 2.  数 ...

  4. Spring事务管理----事物回滚

    Spring的事务管理默认只对未检查异常(java.lang.RuntimeException及其子类)进行回滚,如果一个方法抛出Checked异常,Spring事务管理默认不进行回滚. 改变默认方式 ...

  5. 在 Less 中写 IE 的css hack

    Less中直接在属性后面加hack写法会编译报错的.那么怎么解决呢? 第一种方式: IE7 以display:inline-block为例: less的hack写法: .box{ display: i ...

  6. python--装饰器(附偏函数、断言)

    博客地址:http://www.cnblogs.com/yudanqu/ 概念:装饰器是一个闭包,把一个函数当做参数返回一个替代版的函数,本质上就是一个返回函数的函数 装饰器就是在我们需要的一个函数外 ...

  7. OsharpNS轻量级.net core快速开发框架简明入门教程-Osharp.Redis使用

    OsharpNS轻量级.net core快速开发框架简明入门教程 教程目录 从零开始启动Osharp 1.1. 使用OsharpNS项目模板创建项目 1.2. 配置数据库连接串并启动项目 1.3. O ...

  8. Windows环境下springboot集成redis的安装与使用

    一,redis安装 首先我们需要下载Windows版本的redis压缩包地址如下: https://github.com/MicrosoftArchive/redis/releases 连接打开后如下 ...

  9. python接口自动化(十三)--cookie绕过验证码登录(详解)

    简介 有些登录的接口会有验证码:短信验证码,图形验证码等,这种登录的话验证码参数可以从后台获取的(或者查数据库最直接).获取不到也没关系,可以通过添加cookie的方式绕过验证码.(注意:并不是所有的 ...

  10. 目前比较流行的Python量化开源框架汇总(交易+风险分析工具)

     注:点击框架名称通往Github talib talib的简称是Technical Analysis Library,主要功能是计算行情数据的技术分析指标 numpy 介绍:一个用python实现的 ...