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. 在当前图纸中创建一个表格, AcDbTable 类

    Table 例子学习笔记在这个例子中,ARX向我们展示了ACDBTABLE类的一些基本操作方法,ACDBTABLE类是ACAD2005及其以后的产品,应该是说ACDBDATATABLE的升级产品,Ac ...

  2. bzoj5252 [2018多省省队联测]林克卡特树

    斜率优化树形dp?? 我们先将问题转化成在树上选K+1条互不相交路径,使其权值和最大. 然后我们考虑60分的dp,直接维护每个点子树内选了几条路径,然后该点和0/1/2条路径相连 然后我们会发现最后的 ...

  3. BZOJ_3262_陌上花开_CDQ分治+树状数组

    BZOJ_3262_陌上花开_CDQ分治+树状数组 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的 ...

  4. 监督学习——logistic进行二分类(python)

    线性回归及sgd/bgd的介绍: 监督学习--随机梯度下降算法(sgd)和批梯度下降算法(bgd) 训练数据形式:          (第一列代表x1,第二列代表 x2,第三列代表 数据标签 用 0/ ...

  5. Text-CNN-文本分类-keras

    Text CNN 1. 简介 TextCNN 是利用卷积神经网络对文本进行分类的算法,由 Yoon Kim 在 "Convolutional Neural Networks for Sent ...

  6. Windbg分析高内存占用问题

    1. 问题简介 最近产品发布大版本补丁更新,一商超客户升级后,反馈系统经常奔溃,导致超市的收银系统无法正常收银,现场排队付款的顾客更是抱怨声声.为了缓解现场的情况, 客户都是手动回收IIS应用程序池才 ...

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

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

  8. ES 集群上,业务单点如何优化升级?

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! ES 基础 ES 集群 ES 集群上业务优化 一.ES 基础 ...

  9. 使用Git过程中经常会遇到的问题

    目录 git pull如何强制覆盖本地文件 Git如何同时删除本地分支和远程分支 Git如何撤销最近一次提交 Git撤销本地的最后一次提交 Git撤销最近一次远程提交 如何修改提交信息和文件 修改本地 ...

  10. SQL SERVER 查看近期死锁

    在项目运行的过程中,死锁不可能完全避免,但要尽可能减少死锁的出现, 产生死锁的原因主要是: 1,系统资源不足. 2,进程运行推进的顺序不合适. 3,资源分配不当等. 产生死锁的四个必要条件:- 互斥条 ...