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. BZOJ_1923_[Sdoi2010]外星千足虫_高斯消元+bitset

    BZOJ_1923_[Sdoi2010]外星千足虫_高斯消元 Description Input 第一行是两个正整数 N, M. 接下来 M行,按顺序给出 Charles 这M次使用“点足机”的统计结 ...

  2. 信息论随笔3: 交叉熵与TF-IDF模型

    接上文:信息论随笔2: 交叉熵.相对熵,及上上文:信息论随笔 在读<数学之美>的时候,相关性那一节对TF-IDF模型有这样一句描述:"其实 IDF 的概念就是一个特定条件下.关键 ...

  3. Ubuntu18.04美化主题(mac主题)

    前端时间Ubuntu18.04LTS发布,碰巧之前用的Ubuntu16.04出了一点问题,懒得解决,索性就换了Ubuntu18.04. 成果: 参考博客:https://www.cnblogs.com ...

  4. SpringBoot---页面跳转之WebMvcConfigurerAdapter

    摘要:在springboot中定义自己的方法继承WebMvcConfigurerAdapter方法可以实现扩展springMvc功能,要全面实现接管springmvc就要在自己的方法上加上@Enabl ...

  5. 什么是TensorBoard?

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 回顾前面: 从零开始学TensorFlow[01-搭 ...

  6. 24分钟让AI跑起飞车类游戏

    本文由云+社区发表 作者:WeTest小编 WeTest 导读 本文主要介绍如何让AI在24分钟内学会玩飞车类游戏.我们使用Distributed PPO训练AI,在短时间内可以取得不错的训练效果. ...

  7. Mybatis插入数据返回主键ID

    <insert id="add" parameterType="com.dsa.core.base.model.ProductSync">      ...

  8. DFS(深度优先搜索)

    简介 DFS的过程是一个递归过程,它是从图中的某个顶点开始,首先访问起始点v,然后选择一个与顶点v相邻的且没有被访问的顶点w,以w为起始顶点,在进行DFS,直到图中所有与v相邻的顶点都被访问过为止. ...

  9. C#设计模式整理

    我居然连一月一随笔都没有,啊啊啊,忙死个人 这个随笔主要是记录基于自己学习[美]James W.Cooper著的<C# Design Patterns : A Tutorial>一书中常用 ...

  10. JavaScript对象类型判断注意点

    注意点 不要使用 new Number() . new Boolean() . new String() 创建包装对象:用 parseInt() 或 parseFloat() 来转换任意类型到numb ...